我的情况是,不同功能之间共享相同的通道,当所有这些功能发出信号时,我需要关闭通道。这是我想出来的,但它并不理想,因为我需要处理两个通道,需要发送一个特殊的关键字,而不是使用关闭!功能。还有另一种更好的方法吗?是否有core.async的某些功能可以做到这一点?
(defn shared-chan [n]
(let [in (chan)
out (chan)]
(go-loop [n n]
(if (= n 0)
(do
(async/close! in)
(async/close! out))
(let [in-msg (<! in)]
(if (not= :close in-msg)
(do
(>! out in-msg)
(recur n))
(recur (dec n))))))
[in out]))
答案 0 :(得分:2)
merge
可能会对您有所帮助。根据文件,merge
收集源频道并返回一个频道 包含从中获取的所有值。 ... 这个频道 将在所有源频道关闭后关闭。
因此,基本上您需要为每个功能创建一个频道,然后merge
将它们合并为一个。
答案 1 :(得分:0)
您可以使用take
传感器生成此共享频道。例如,如果您想要3个项目的自动关闭频道:
user> (require '[clojure.core.async :as a])
nil
user> (def shared-ch (a/chan 3 (take 3)))
#'user/shared-ch
user> (a/go-loop []
(when-let [val (a/<! shared-ch)]
(println :reading val)
(recur)))
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x6bb1dee5 "clojure.core.async.impl.channels.ManyToManyChannel@6bb1dee5"]
user> (a/>!! shared-ch 1)
true:reading 1
user> (a/>!! shared-ch 2)
true:reading 2
user> (a/>!! shared-ch 3)
true:reading 3
user> (a/>!! shared-ch 4)
false
user> (a/>!! shared-ch 5)
false
您可以看到,一旦换能器耗尽,通道就已关闭(在写入尝试后返回false
)