为了账号安全,请及时绑定邮箱和手机立即绑定

如何在返回之前合并两个 gorountines 的结果?

如何在返回之前合并两个 gorountines 的结果?

Go
临摹微笑 2021-10-25 20:12:41
我在 Go 应用程序中有一个 Web 请求处理程序,需要向其他 URL 发出 2 个以上的请求。我想从每个 URL 收集结果,将每个结果合并到一个 JSON 对象中,然后通过我的请求处理程序返回。请求不相互依赖,不需要排序。在 Go 中执行此操作的最佳模式是什么?我应该使用频道和一个WaitGroup吗?
查看完整描述

2 回答

?
开满天机

TA贡献1786条经验 获得超13个赞

对于简单的事情,我会使用一组局部变量和一些设置这些变量的 goroutine,以及一个等待组来了解一切何时完成:


    var a string

    var b string

    wg := sync.WaitGroup{}

    wg.Add(2)

    go func(){

        time.Sleep(5 * time.Second) // make a request

        a = "foo"

        wg.Done()

    }()

    go func(){

        time.Sleep(3 * time.Second) // make a request

        b = "bar"

        wg.Done()

    }()

    wg.Wait()

    fmt.Println(a,b) //combine results


如果您想要更复杂的行为,如超时或部分结果,那么您可能希望您的子请求在您可以选择的频道上传达结果:


// make sure to buffer to max number of senders so garbage collection can clean up

// if we time out

ch := make(chan string, 2)

go func() {

    time.Sleep(5 * time.Second) // make a request

    ch <- "foo"

}()

go func() {

    time.Sleep(2 * time.Second) // make a request

    ch <- "bar"

}()

results := []string{}

timeout := time.After(4 * time.Second)

Loop:

for {

    select {

    case r := <-ch:

        results = append(results, r)

        if len(results) == 2 {

            break Loop

        }

    case <-timeout:

        break Loop

    }

}

fmt.Println(results)


这并不能完全保留顺序,但如果这很重要,您可以创建另一个频道。无论如何,这就是一般的想法。


查看完整回答
反对 回复 2021-10-25
  • 2 回答
  • 0 关注
  • 180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信