Clojure 创建需要关闭多次的频道

Clojure 创建需要关闭多次的频道,clojure,channel,core.async,Clojure,Channel,Core.async,我的情况是,同一个通道在不同的功能之间共享,当所有这些功能发出信号时,我需要关闭通道。这是我想到的,但它并不理想,因为我需要处理两个频道,需要发送一个特殊的关键字,而不是使用关闭!功能。还有其他更好的方法吗?core.async有什么功能可以做到这一点吗 (defn shared-chan [n] (let [in (chan) out (chan)] (go-loop [n n] (if (= n 0) (do (as

我的情况是,同一个通道在不同的功能之间共享,当所有这些功能发出信号时,我需要关闭通道。这是我想到的,但它并不理想,因为我需要处理两个频道,需要发送一个特殊的关键字,而不是使用关闭!功能。还有其他更好的方法吗?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]))
(defn共享chan[n]
(让[进来(陈)
出(陈)]
(转圈[n]
(如果(=n0)
(做
(异步/关闭!输入)
(异步/关闭!关闭))
(让[输入味精(!输出味精)
(重复(n))
(再次出现(第n(()()())))
[输入输出])
可能会帮助您。根据文档,
合并

获取源通道的集合并返回一个 包含从中获取的所有值…通道 将在所有源通道关闭后关闭


因此,基本上您需要为每个函数创建一个通道,然后将它们合并成一个通道。

您可以使用
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
user>(需要“[clojure.core.async:as a]”
无
用户>(def共享通道(a/chan 3(take 3)))
#'用户/共享ch
用户>(a/go循环[]
(当让[val(a/(a/>共享通道1)时)
正确:阅读1
用户>(a/>!!共享通道2)
正确:阅读2
用户>(a/>!!共享通道3)
正确:阅读3
用户>(a/>!!共享通道4)
假的
用户>(a/>!!共享通道5)
假的
您可以看到,一旦传感器耗尽,通道已关闭(因为写入尝试后返回
false