这是来自 golang 上下文页面https://blog.golang.org/context的代码片段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 }}这种方法的描述说httpDo 函数运行 HTTP 请求并在新的 goroutine 中处理其响应。如果 ctx.Done 在 goroutine 退出之前关闭,它将取消请求:这里的请求是如何取消的?在我看来,即使上下文完成,我们仍在等待请求的结果?这有什么帮助?
2 回答
MMTTMM
TA贡献1869条经验 获得超4个赞
诀窍是 context 被传递给http.DefaultClient.Do(req)using req = req.WithContext(ctx),因此req参数将 context 保留在里面。函数使用它,并在原始上下文 ( ) 被取消http.DefaultClient.Do()后立即退出。ctx
实际上我不会说“httpDo 函数取消请求”,它是ctx由调用者取消的httpDo。在这里使用 goroutine 是有争议的,我们可以直接返回f(http.DefaultClient.Do(req))
慕田峪9158850
TA贡献1794条经验 获得超8个赞
Do(req)取消上下文后将立即退出并出现错误。你是对的,我们仍在等待一个值,c但我们应该在上下文取消后几乎立即得到它。此外,无需等待Do(req). 根据您的用例,可以提前从函数返回。
当然,随机func Foo(ctx context.Context)函数不需要监听上下文,因此假设所有获取上下文的函数都会正确处理取消是不安全的。您应该根据文档和/或代码采取行动。
- 2 回答
- 0 关注
- 181 浏览
添加回答
举报
0/150
提交
取消
