【问题标题】:Structuring clojure code with go blocks使用 go 块构建 clojure 代码
【发布时间】:2016-03-21 18:01:12
【问题描述】:

我将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 中使用&lt;!,我需要将它放在go 块中。 现在我在route-function 中使用这个go 块的频道。这看起来很单调吗?我担心不会将api-call-1-response-parse 甚至:body 暴露为route-function 的频道。

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

【问题讨论】:

    标签: asynchronous clojure core.async


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 2017-12-05
      • 2020-04-01
      • 1970-01-01
      • 2016-12-12
      • 2012-12-21
      • 1970-01-01
      • 2018-04-01
      • 2019-09-02
      • 1970-01-01
      相关资源
      最近更新 更多