为什么`core.async / pipeline`会返回一个频道?

时间:2016-11-07 20:16:06

标签: clojure core.async

我刚注意到pipeline系列返回了一个channel,它似乎完全独立于管道及其相关渠道的目的而运作。

请注意,在以下示例中,您可以>! / <!pipes分别a> / b>,而且它们无关。

据我了解,pipeline应为无操作,并在设置niltransduc到{{1}的副作用时返回a> }}

那么,我错过了什么,为什么b>会返回pipeline

channel

2 个答案:

答案 0 :(得分:8)

当没有更多要复制的元素时,您将返回一个已关闭的频道。也就是说,在a>关闭后,其中的所有元素都已大写并放在b>上。你可以从结果通道<!找出流水线操作何时完成,如果你在意,或者你可以扔掉通道。你可能不应该写信。

这是许多异步操作的常见模式,实际上经常会隐式发生:每个go块返回一个通道,当块完成时,该通道会将块的返回值写入其中,并且许多异步操作使用一个go块作为返回值,因此您可以自动获得此“完成工作”的通道。

答案 1 :(得分:3)

要解释@ amalloy的答案,在以下示例中,a>b>在能够完成时会将true置于其上。由于chan>是无缓冲的,因此在另一个进程取消它们之前无法完成,即最后的println

如果chan>被缓冲,a>b>可以立即>!,所以立即打印。

(def chan> (chan 4))
(def a> (go (>! chan> "Apple")))
(go (println "from a>: " (<! a>)))
(def b> (go (>! chan> "Ball")))
(go (println "from b>: " (<! b>)))

(go (println "from chan>: "(<! chan>)))
;; => from chan>: Apple
;; => from a>: true
(go (println "from chan>: "(<! chan>)))
;; => from chan>: Ball
;; => from b>: true

这与pipeline s背后的想法相同。

;; Pipeline-specific

(def a> (chan))
(def b> (chan))
(def p> (pipeline 4 b> (map clojure.string/upper-case) a>))

;; this won't happen until `a>` `close!`s
(go (println "pipeline is done: " (<! p>)))

;; execute the following 2 lines ad lib
(go (>! a> "hi there"))
(go (println "from b>: " (<! b>)))

(comment
  (close! a>) ; triggers the "pipeline is done"
  (close! b>)) ; doesn't trigger it, but `b>` now only returns nil when taking