使用 go 块构建 clojure 代码

Structuring clojure code with go blocks

我正在使用 jet 作为异步环适配器。 Jet 还带有异步 http 客户端,它 return 是一个通道,其值 :body 也是一个通道。

此外,异步服务器路由处理程序可以 return 一个映射,其 :body 键可以包含一个通道。当此通道关闭时,响应将 return 发送给客户端。

我正在编写以下 go 代码:

 (defn- api-call-1 []
     (go (-> (jet-client/get "api-url-1")
             <!
             :body                ;; jet http client :body is also a channel.
             <!
             api-call-1-response-parse)))


 (defn- api-call-2 []
     (go (-> (jet-client/get "api-url-2")
             <!
             :body
             <!
             api-call-2-response-parse)))


 (defn route-function []
    (let [response-chan (chan)]
      (go 
        (let [api-call-1-chan (api-call-1) ;; using channel returned by go
              api-call-2-chan (api-call-2)]
              (-> {:api-1 (<! api-call-1-chan)
                   :api-2 (<! api-call-2-chan)}
                  encode-response
                  (>! response-chan)))
        (close! response-chan))
    ;; for not blocking server thread, return channel in body
    {:body response-chan :status 200}))

在我的route-function中,我无法阻止。

虽然这段代码工作正常,但在 api-call-1 中使用 go 是错误的吗?

我发现要在 api-call-1 中使用 <!,我需要将它放在 go 块中。 现在我在 route-function 中使用这个 go 块的频道。这看起来是单一的吗?我担心不会将 api-call-1-response-parse 甚至 :body 作为频道公开给 route-function.

构建 go 块代码和函数的正确方法是什么? 我应该关心函数 api-call-1/2 中额外的 go 块吗?

您所拥有的看起来很像我在生产环境中所拥有的等效代码。这是非常惯用的,所以我认为您的代码结构正确。

core.async 停车操作不能跨越函数边界这一事实源于这样一个事实,即它被编写为一个宏并且需要一次处理整个代码块(或者至少在它的词汇可用时) ).这往往会使所有 core.async 代码都以您正在使用的模式出现。