You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang Context Done信号如何实现请求取消?代码逻辑疑问解析

How Does Context's Done Signal Cancel the Request?

Great question! Let's unpack this code and the mechanism step by step to clear up your confusion.

First, let's start with the most critical line that makes the cancellation work:

req = req.WithContext(ctx)

This creates a new copy of the HTTP request bound to the provided ctx. The Go standard library's http.Client.Do method is built to listen for signals from the request's context. When ctx.Done() is closed (either via an explicit cancel call, timeout, or deadline), the Do method will immediately interrupt the ongoing HTTP request: it closes the underlying TCP connection, stops waiting for the server's response, and returns an error indicating the context was canceled. This is where the actual request cancellation happens—before we even get to the select block.

Now let's walk through the rest of the code to see how it all ties together:

  1. The goroutine runs c <- f(http.DefaultClient.Do(req)):

    • When the context is canceled, Do(req) quickly returns a cancellation error instead of blocking indefinitely.
    • The function f then processes this error (or a successful response if the request finished before cancellation), and sends the result to the c channel.
  2. The select block handles two cases:

    • Case 1: <-ctx.Done() triggers first: This means the context was canceled before the request/processing finished. We still do <-c here to wait for f to complete its work—this prevents goroutine leaks, as we need to ensure the goroutine exits cleanly before returning. After that, we return ctx.Err() to let the caller know the operation was canceled due to the context.
    • Case 2: err := <-c triggers first: This means the request and f's processing finished before the context was canceled. We just return the resulting error (or nil if everything worked).

Your confusion about "waiting for the request result even after the context is done" makes sense at first glance, but remember: by the time <-ctx.Done() is triggered, the Do method has already been told to cancel the request. The <-c is just waiting for the cleanup (the f function to finish) to complete, not waiting for a full, successful response from the server. The request itself is no longer in progress—it's already been terminated by the context signal.

内容的提问来源于stack exchange,提问作者Jeff P Chacko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 22:07:42