我无法理解 Go 并发模式中此示例的逻辑:上下文
func httpDo(ctx context.Context, req *http.Request, f func(*http.Response, error) error) error {
// Run the HTTP request in a goroutine and pass the response to f.
c := make(chan error, 1)
req = req.WithContext(ctx)
go func() { c <- f(http.DefaultClient.Do(req)) }()
select {
case <-ctx.Done():
<-c // Wait for f to return.
return ctx.Err()
case err := <-c:
return err
}
}
在此之前,据说:
Done
方法返回充当取消信号的通道 到代表Context
运行的函数:当通道 关闭,功能应该放弃工作并返回。
这看起来相当于只等待<-c
,根本没有case <-ctx.Done()
。那么,有什么意义呢?
上下文可能会取消Do
调用。case <-ctx.Done()
明确指出发生了这种情况。
事实上,我们可以假设Do
调用将返回一个nil
http.Response
,并且当这种情况发生时,函数f
将返回一个错误。但我们不知道为什么f
会收到一个nil
http.Response
作为输入参数。
指令case err := <-c:
处理在f
内部产生错误的情况。
它不等同于只等待<-c
。该示例在上下文关闭时返回不同的值 (ctx.Err()
(。