如何让我的函数 return 立即进入 Slack?

How to make my function return to Slack right away?

我正在尝试为 Slack 开发一个简单的 API,我想 return 立即向用户提供一些东西以避免 3000 毫秒超时。

这是我的问题:

  1. 为什么 This should be printed to Slack first 没有立即打印出来,而是我只收到最后一条消息,即 The long and blocking process completed?但是它出现在 ngrok 日志中。

  2. 为什么我的函数仍然达到 3000 毫秒限制,即使我已经在使用 go 例程?是因为done频道吗?

func testFunc(w http.ResponseWriter, r *http.Request) {
    // Return to the user ASAP to avoid 3000ms timeout.
    // But this doesn't work. Nothing is returned but
    // the message appeared in ngrok log.
    fmt.Fprintln(w, "This should be printed to Slack first!")

    // Get the response URL.
    r.ParseForm()
    responseURL := r.FormValue("response_url")

    done := make(chan bool)

    go func() {
        fmt.Println("Warning! This is a long and blocking process.")
        time.Sleep(5 * time.Second)

        done <- true
    }()

    // This works! I received this message. But I still reached the 3000ms timeout.
    func(d bool) {
        if d == true {
            payload := map[string]string{"text": "The long and blocking process completed!"}
            j, err := json.Marshal(payload)

            if err != nil {
                w.WriteHeader(http.StatusInternalServerError)
            }

            http.Post(responseURL, "application/json", bytes.NewBuffer(j))
        }
    }(<-done)
}

我正在学习golang阶段。这是我的理解: 1. 任何对通道的操作都是阻塞的 2. 您正在

中的频道上写作
    go func() {
        fmt.Println("Warning! This is a long and blocking process.")
        time.Sleep(5 * time.Second)

        done <- true
    }()
  1. 调度程序仍在 main 函数中移动并尝试从通道中读取,但它正在等待查看是否有内容写入通道。所以它被阻塞了,当上面的函数通过在通道上写入完成时,控件返回并且 main 再次开始执行。

注:高手能解释的更好

http.ResponseWriter 流默认缓冲。如果你想将数据实时发送到客户端(例如 HTTP SSE),你需要在每个 'event':

之后刷新流
wf, ok := w.(http.Flusher)

if !ok {
    http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
    return
}

fmt.Fprintln(w, "This should be printed to Slack first!")

wf.Flush()

刷新很昂贵 - 所以利用 go 的缓冲。一旦您的处理程序最终退出,总会有一个隐式刷新(因此您看到输出的原因 'late')。