這是來自 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條經驗 獲得超7個贊
Do(req)
取消上下文后將立即退出并出現錯誤。你是對的,我們仍在等待一個值,c
但我們應該在上下文取消后幾乎立即得到它。此外,無需等待Do(req)
. 根據您的用例,可以提前從函數返回。
當然,隨機func Foo(ctx context.Context)
函數不需要監聽上下文,因此假設所有獲取上下文的函數都會正確處理取消是不安全的。您應該根據文檔和/或代碼采取行動。
- 2 回答
- 0 關注
- 147 瀏覽
添加回答
舉報
0/150
提交
取消