2 回答

TA贡献1775条经验 获得超11个赞
在你的陈述之前,你实际上是在等待所有的goroutines回来。wg.Wait()
select
这样做的问题是,我想在收到错误后立即返回错误
我假设您的意思是,一旦其中任何一个返回错误,就停止运行goroutines。
在这种情况下,您可以使用来管理取消,但更好的是错误组。组
,它很好地结合了上下文功能和同步:context.Context
包错误组为处理常见任务的子任务的 goroutine 组提供同步、错误传播和上下文取消。
特别是Group.Go
:
返回非 nil 错误的第一个调用将取消该组;其错误将由 Wait 返回。
import (
"sync"
"runtime"
"fmt"
"errors"
"golang.org/x/sync/errgroup"
)
func try() (bool, error) {
errg := new(errgroup.Group)
s := []int{0,1,2,3,4,5}
for i, val := range s {
i := i
val := val
errg.Go(func() error {
return func(i int, val int) error {
if i == 3 {
return errors.New("one error")
} else {
return nil
}
}(i, val)
})
}
if err := errg.Wait(); err != nil {
// handle error
}
return true, nil
}
https://play.golang.org/p/lSIIFJqXf0W

TA贡献1839条经验 获得超15个赞
我发现坟墓对此很有用。下面是一个精简的非工作示例,它显示了要点,而无需在循环中处理变量封装之类的事情。它应该给你这个想法,但我很乐意澄清任何一点。
package main
import (
"fmt"
"gopkg.in/tomb.v2"
"sync"
)
func main() {
ts := tomb.Tomb{}
s := []int{0,1,2,3,4,5}
for i, v := range s {
ts.Go(func() error {
// do some work here or return an error, make sure to watch the dying chan, if it closes,
//then one of the other go-routines failed.
select {
case <- ts.Dying():
return nil
case err := <- waitingForWork():
if err != nil {
return err
}
return nil
}
})
}
// If an error appears here, one of the go-routines must have failed
err := ts.Wait()
if err != nil {
fmt.Println(err)
}
}
- 2 回答
- 0 关注
- 98 浏览
添加回答
举报