创建需要多次关闭的频道

时间:2016-06-01 09:01:54

标签: clojure channel core.async

我的情况是,不同功能之间共享相同的通道,当所有这些功能发出信号时,我需要关闭通道。这是我想出来的,但它并不理想,因为我需要处理两个通道,需要发送一个特殊的关键字,而不是使用关闭!功能。还有另一种更好的方法吗?是否有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]))

2 个答案:

答案 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