使用 go 块构建 clojure 代码



我正在使用jet作为异步环形适配器。Jet还带有异步http-client,它返回一个通道,其值:body也是一个通道。

此外,异步服务器路由处理程序可以返回其:body键可以包含通道的映射。关闭此通道时,响应将返回到客户端。

我正在编写以下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 代码以您正在使用的模式出现。

最新更新