go - 同时调用多个服务的模式每个服务返回值和错误

标签 go

我仍在体验如何充分利用 channel 。 我有 5 个出站服务调用(大约需要 2 分钟返回),每个都给了我一对返回值。 例如func serviceCall()(T, 错误)

我想让它们并发,但我发现代码很长。

基本上,我必须创建 5 个 channel ,5 个结构来保存返回值。

我写了一个简单的例子来表达这个场景,我想知道这个场景的模式是什么,我如何才能让这段代码变得更好。

主要包

import (
    "fmt"
    "math/rand"
    "time"
    "log"
)

// goal: run multiple functions concurrently and process the results.
func main() {
now := time.Now()
    // method1
    type res1 struct {
        news string
        err  error
    }
    type res2 struct {
        n   int
        err error
    }

    ch1 := make(chan *res1)
    ch2 := make(chan *res2)

    go func() {
        var res res1
        res.news, res.err = news1()
        ch1 <- &res
    }()

    go func() {
        var res res2
        res.n, res.err = news2()
        ch2 <- &res
    }()

    one := <-ch1
    if one.err != nil {
        log.Fatal(one.err)
    }
    fmt.Println("news1: ", one.news)

    two := <-ch2
    if two.err != nil {
        log.Fatal(two.err)
    }
    fmt.Println("news2: ", two.n)

    fmt.Println("time elapsed: ", time.Since(now))

}

// first sleeps 5 seconds and returns random number or error.
func news1() (string, error) {
    time.Sleep(time.Second * 5)
    return "new1 is here.", nil
}

// second sleeps random seconds and returns random number or error.
func news2() (int, error) {
    n := rand.Intn(20)
    time.Sleep(time.Duration(n) * time.Second)

    return n, nil
}

最佳答案

对此没有单一的模式。有不同的方法来实现它。最简单的可能是 WaitGroup ,它根本不需要 channel 。这个模式看起来像这样:

func dostuff() {
    var result1 int
    var result2 string
    var resultN SomeStruct
    var err1, err2, errN error

    wg := sync.WaitGroup{}

    wg.Add(1)
    go func() {
        defer wg.Done()
        result1, err1 = doStuff1()
    }

    wg.Add(1)
    go func() {
        defer wg.Done()
        result2, err2 = doStuff2()
    }

    // repeat as often as you like

    wg.Add(1)
    go func() {
        defer wg.Done()
        resultN, errN = doStuffN()
    }

    wg.Wait()
    // handle results and errors
}

这种方法最明显的缺点是您无法灵活地在出现错误时中止任何未完成的操作。这对您来说可能重要,也可能不重要。

关于go - 同时调用多个服务的模式每个服务返回值和错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56281115/

相关文章:

go - 处理多语言 Go Web 应用程序的标准/惯用方法是什么?

json - 转换 JSON 消息的最佳实践

sql - 在 go 中结合 row.Scan 和 rows.Scan 接口(interface)?

go - 从 Twitter 库搜索中获取数据到 Go 中的结构

go - 无法在 Fedora 31 中安装 gopls

go - 如何获取FaunaDB中包含子字符串的文档

json - 是否可以在Go中添加嵌套的json "as is"?

json - Golang post 返回 json 响应

go - 使用无服务器工作流程 go sdk 时出现间歇性 JSON 解码错误

GoLang Telegram-bot-api 如何询问位置?