如何在执行响应中不需要的计算之前向客户端发送响应

Roh*_*ule 2 http response go goroutine

我们可以使用如下语句发送响应(或在用户端写入):

json.NewEncoder(w).Encode("some data")
Run Code Online (Sandbox Code Playgroud)

在执行一些计算部分之前,在 api 中,这些计算部分不需要响应,但需要存储在数据库中。我想我们可以在更短的时间内向用户提供响应,并且函数的其他部分将继续工作直到返回语句。

如果我的思考方向错误,请纠正我。

icz*_*cza 6

一种方法是完成另一个 Goroutine 中的响应不需要的额外工作:

func someHandler(w http.ResponseWriter, r *http.Request) {
    go func() {
        // Do anything here, this won't delay the response
        // But don't touch the writer or request, as they may not be available here
    }()

    if err := json.NewEncoder(w).Encode("some data"); err != nil {
        log.Printf("Error sending response: %v", err)
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,在启动的 gorotuine 中,您不能使用 或http.ResponseWriterhttp.Request因为它们只有在您从处理程序返回之前才有效。如果您需要它们的某些内容,则必须在启动 goroutine 之前复制所需部分。

如果您想在从处理程序返回之前完成附加任务,您仍然可以使用 goroutine,并使用 async.WaitGroup等待它完成,然后才从处理程序返回。您可以也可以不刷新响应:

func someHandler(w http.ResponseWriter, r *http.Request) {
    wg := &sync.WaitGroup{}
    wg.Add(1)
    go func() {
        defer wg.Done()

        // You may use the writer and request here
    }()

    if err := json.NewEncoder(w).Encode("some data"); err != nil {
        log.Printf("Error sending response: %v", err)
    }

    // Optionally you may flush the data written so far (icnluding HTTP headers)
    if flusher, ok := w.(http.Flusher); ok {
        flusher.Flush()
    }

    wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)

请注意,这里允许 goroutine 使用 and http.ResponseWriterhttp.Request因为处理程序在附加任务完成之前不会返回。