我一个接口里边,需要多次操作数据库,现在想通过协程来实现。 下边这个 demo 是一个样例, 我在 resp 怎么区分协程的返回值,这里边还有些不太清晰。
func main() {
var ch = make(chan []byte)
go request("https://www.baidu.com", ch)
go request("https://www.taobao.com", ch)
go request("https://www.google.com", ch)
i := 0
timer := time.NewTimer(time.Second * 3)
L:
for {
select {
case <-timer.C:
break L
case resp := <-ch:
fmt.Printf("%d\n", len(resp))
// 接收 3 个之后关闭 chan
i++
if i == 3 {
close(ch)
break L
}
}
}
// more code...
}
1
catVSdog 2023-01-15 10:22:20 +08:00
你是要区分每个协程的返回值吗?不同的协程对应不同处理方式?
那么再构建一个一个结构体,例如: type CRes struct { } |
2
catVSdog 2023-01-15 10:28:01 +08:00 2
你是要区分每个协程的返回值吗?不同的协程(或者说:不同的数据库)对应不同处理方式?
那么再构建一个一个结构体,例如: type CRes struct { ChannelType int // taobao:1, baidu:2, google:3 Res interfact{} } ch := make(chan CRes) 每个协程函数返回 CRes ,然后将 CRes 返回到 channel 中。在接受、处理 channel 的函数中,根据不同的 channelType 进行处理 |
3
awanganddong OP 明白了,谢谢你。
|
4
awanganddong OP 我修改后的 demo 发下
package main import ( "fmt" "time" ) type CRes struct { ChannelType int Res interface{} } func main() { var ch = make(chan CRes) go test1(ch) go test2(ch) for i := 0; i < 2; i++ { select { case <-time.After(time.Second * 5): fmt.Println("超时操作") break case resp := <-ch: if resp.ChannelType == 1 { fmt.Printf("这是 1 的数据") } if resp.ChannelType == 2 { fmt.Printf("这是 2 的数据") } break default: fmt.Println("资源已满,请稍后再试") } } } func test1(ch chan CRes) { res := CRes{ ChannelType: 1, Res: nil, } ch <- res } func test2(ch chan CRes) { res := CRes{ ChannelType: 2, Res: nil, } ch <- res } |
5
jorneyr 2023-01-15 20:14:16 +08:00
md5(url) 作为任务的 ID ,返回的时候也对应的带上这个 ID 。
|
6
morty0 2023-01-16 09:57:56 +08:00
context 带个 id 进去
|
7
ryalu 2023-01-16 15:48:16 +08:00
没必要这么复杂吧,直接用 errgroup 。最近有个协程的库看起来还可以 https://github.com/sourcegraph/conc
|