我创建了一个API,在处理请求后,它会发送一个响应,并启动一个后台goroutine,记录一些消息.在处理API请求后,我使用了"延迟"来执行goroutine.

以下是代码片段:

sendResponse伪代码:

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

响应 struct :

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秒),i的值从1打印到10.

但在实际结果中,API响应是在10秒后收到的.

据我所知,延迟函数是在周围(或当前/封闭)函数终止或返回后调用的.

因此,我必须首先接收API响应,然后必须记录'I'的值.但在我的情况下,经过几秒钟(10秒)后,我收到了响应.如果"i"的值相当大,这将是一个主要问题.

如果有人能解释这种异常行为并提供可能的解决方案,这将很有帮助.

推荐答案

在处理API请求后,我使用了"延迟"来执行goroutine.

defer不会启动goroutine.它对调用的goroutine执行延迟函数.很有可能响应被缓存,写入其中的数据在处理程序返回之前不会被刷新.

如果要在新的goroutine中执行日志(log)记录,请使用以下go关键字:

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

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

Go相关问答推荐

我不能让GIO画一个按钮

如何用';贪婪原则';正确地

Caddy服务器try 打开端口80而不是8090.

获取 nil 指针类型的 reflect.Value

Golang 创建一个带有处理程序的模拟数据库并使用接口调用数据库

将 struct 转换为 CSV 字符串

如何使用 go 包设置标头键和值:shurcooL/graphql 或 hasura/go-graphql-client?

如何将整数哈希细分为范围

如何在 Golang http.Request 对象中读取自定义 ajaxParams

如何在模板中传递和访问 struct 片段和 struct

如何过滤来自 fsnotify 的重复系统消息

fmt.Printf() 标志 '0' 不会被字符串忽略

如何在 helm 中将字符串连接到 .AsConfig 的结果?

如何在循环中旋转图像以便在 golang 中创建 GIF?

Go:如何创建一个可以提供配置文件中描述的 url 的服务器

go mod tidy 错误消息:但是 go 1.16 会 Select

如何在 Go 中使用 Pact 返回错误请求(400、500)?

如何解决在mac m1中运行gcc失败退出状态1?

Go 泛型是否与 LINQ to Objects 等效?

在 Go 中表达函数的更好方法( struct 方法)