Golang 'defer'导致发送(接收)API响应延迟

vhmi4jdf  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(126)

我已经创建了一个API,它在处理请求后发送一个响应,并启动一个后台goroutine来记录一些消息。我已经使用了'defer'来在API请求被处理之后执行goroutine。
以下是代码片段:
sendResponse伪代码:

{
  ...
  res.Header().Add("Content-Type", "application/json")
  json.NewEncoder(res).Encode(response)
}

响应结构:

type Response struct {
   StatusCode int16  `json:"statusCode"`
   Message    string `json:"message"`
}

API主体:

{ 
 ...
 defer logMsgs()
 sendAPIResponse()
 return
}

logMsgs伪代码:

func logMsgs(){
   time.Sleep(10*time.Seconds)
   wg := sync.Waitgroup{}
   wg.Add(1)
   go func(){
      for i = 1 to 10
         print(i)
      wg.Done()
   }()
   wg.Wait()
}

预期结果是接收API响应,并且在几秒(这里是10 s)之后,从1到10打印‘i’的值。
但在实际结果中,10 s后收到API响应。
根据我的理解,defer函数是在周围(或当前/封闭)函数终止或返回之后调用的。
因此,我必须首先接收API响应,并且必须记录'i'的后续值。但在我的情况下,我在几秒钟(10秒)后收到了响应。如果“i”的值非常大,这将是一个主要问题。
如果有人解释这种异常行为并提供可能的解决方案,这将是有帮助的。谢谢

mzillmmw

mzillmmw1#

我已经使用了'defer'来在API请求被处理之后执行goroutine。
defer不会启动goroutine。它在调用的goroutine上执行deferred函数。而且很有可能响应被缓存,写入其中的数据直到您从处理程序返回时才被刷新。
如果你想在一个新的goroutine中执行日志记录,可以像这样使用go关键字:

defer func() {
    go logMsgs()
}()
sendAPIResponse()
return

但是请注意,从处理程序返回后,启动的goroutine不能访问请求和响应特定的对象,因为它们可能会被新请求重用。因此,保存/传递记录器所需的所有内容,以便在从处理程序返回后安全地使用它们。

相关问题