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