go - 等待多个 goroutine 的结果

标签 go channel goroutine

我正在寻找一种在 go 中异步执行两个函数的方法,它们返回不同的结果和错误,等待它们完成并打印两个结果。此外,如果其中一个函数返回错误,我不想等待另一个函数,而只是打印错误。
例如,我有这个功能:

func methodInt(error bool) (int, error) {
    <-time.NewTimer(time.Millisecond * 100).C
    if error {
        return 0, errors.New("Some error")
    } else {
        return 1, nil
    }
}

func methodString(error bool) (string, error) {
    <-time.NewTimer(time.Millisecond * 120).C
    if error {
        return "", errors.New("Some error")
    } else {
        return "Some result", nil
    }
}

这里https://play.golang.org/p/-8StYapmlg是我如何实现它,但我认为它有太多代码。它可以通过使用 interface{} 来简化,但我不想这样。我想要一些更简单的东西,例如,可以在 C# 中使用 async/await 实现。可能有一些库可以简化这种操作。

更新:感谢您的回复!我得到帮助的速度真是太棒了!我喜欢 WaitGroup 的用法。它显然使代码对更改更加健壮,因此我可以轻松地添加另一个异步方法,而最终无需更改方法的确切计数。但是,与 C# 中的相同代码相比,仍然有很多代码。我知道在 go 中我不需要将方法显式标记为异步,使它们实际上返回任务,但是方法调用看起来更简单,例如,考虑这个链接 actually catching exception is also needed
顺便说一句,我发现在我的任务中我实际上不需要知道我想要运行异步的函数的返回类型,因为它无论如何都会被编码为 json,现在我只是在 go 的端点层调用多个服务-成套工具。

最佳答案

您应该为错误和结果创建两个 channel ,然后如果没有错误则首先读取错误然后读取结果,此示例应该适用于您的用例:

package main

import (
    "errors"
    "sync"
)

func test(i int) (int, error) {
    if i > 2 {
        return 0, errors.New("test error")
    }
    return i + 5, nil
}

func test2(i int) (int, error) {
    if i > 3 {
        return 0, errors.New("test2 error")
    }
    return i + 7, nil
}

func main() {
    results := make(chan int, 2)
    errors := make(chan error, 2)
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        result, err := test(3)
        if err != nil {
            errors <- err
            return
        }
        results <- result
    }()
    wg.Add(1)
    go func() {
        defer wg.Done()
        result, err := test2(3)
        if err != nil {
            errors <- err
            return
        }
        results <- result
    }()

    // here we wait in other goroutine to all jobs done and close the channels
    go func() {
        wg.Wait()
        close(results)
        close(errors)
    }()
    for err := range errors {
        // here error happend u could exit your caller function
        println(err.Error())
        return

    }
    for res := range results {
        println("--------- ", res, " ------------")
    }
}

关于go - 等待多个 goroutine 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60544077/

相关文章:

Golang协程错误 "all goroutines are asleep - deadlock!"

select - 当涉及多个 channel 时,select 如何工作?

go - 从处理程序函数返回响应

pointers - 使用指向外部结构的指针时如何使结构在其 Go 例程之外生存

go - 尝试在 golang 中解码 gob 时出现 "extra data in buffer"错误

go - golang channel 的分段违规

go - 如何匹配 text/plain 类型的流响应与 PACT GO?

go - go 中的非阻塞 channel 操作。发送?

mongodb - 如何删除 Mongodb/Golang 中的数组项?

go - 我应该使用 go mod 提交 vendor 目录吗?