橙
2024-12-20
来自北京
func TestCancel(t *testing.T) { results := make([]string, len(urls)) // 用WithContext函数创建Group对象 eg, ctx := errgroup.WithContext(context.Background()) for index, url := range urls { url := url index := index // 调用Go方法 eg.Go(func() error { select { case <-ctx.Done(): // select-done模式取消运行 return errors.New("task is cancelled") default: // Fetch the URL. resp, err := http.Get(url) if err != nil { return err // 返回错误 } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return err // 返回错误 } results[index] = string(body) return nil } }) } // Wait for all HTTP fetches to complete. // 等待所有任务执行完成,并对错误进行处理 if err := eg.Wait(); err != nil { fmt.Println("Failured fetched all URLs.") } } 这个方法感觉直接用可以cancle的context会不会比较好,如果检测到错误直接cancel掉。现在感觉这个例子虽然支持cancel,虽然在讲cancel,但是例子没有支持cancel,看起来怪怪的。
展开
lJ
2024-12-20
来自江苏
可以基于 WaitGroup 和一个错误通道(error channel,容量不小于控制的协程并发数,避免阻塞)来收集并发协程中的错误信息,任务协程发生的错误写入err channel中,开启一个协程读取err channel。也可以初始化一个全局的错误切片errs,在协程出错时将err赋值给errs。 开源实现有 1、github.com/facebookgo/errgroup,扩展了标准库的sync.WaitGroup,errors收集协程执行时发生的错误 type Group struct { wg sync.WaitGroup mu sync.Mutex errors MultiError } 2、github.com/vardius/gollback,gollback.All方法返回所有的错误 本质上都是通过err切片保存任务协程中的错误信息