使用core.async等待n个通道

时间:2015-08-06 14:45:04

标签: clojure clojurescript core.async

以同样的方式from datetime import datetime def __init__(self, *args, **kwargs): super(MyModel, self).__init__(*args, **kwargs) self.old_published = self.published def save(self, *args, **kwargs): if self.old_published != self.published and self.published: self.pub_date = datetime.now() super(Model, self).save(*args, **kwargs) 等待其中一个 n个频道获取值,我正在寻找等待所有 n的惯用方法获得价值的渠道。

我需要这个,因为我“生成”n块来处理异步任务,我想知道它们何时完成。我确信有一种非常漂亮的方法来实现这一目标。

2 个答案:

答案 0 :(得分:11)

使用core.async map功能:

(<!! (a/map vector [ch1 ch2 ch3]))
;; [val-from-ch-1 val-from-ch2 val-from-ch3]

答案 1 :(得分:5)

您可以说(mapv #(async/<!! %) channels)

如果您希望在到达时处理单个值,然后在最终通道生成值后执行一些特殊操作,则可以利用alts! / alts!!获取通道向量的事实,它们是函数,而不是宏,因此您可以轻松传入动态构造的向量。

因此,您可以使用alts!!等待n个频道的初始收集,然后在其余频道等上再次使用它。

(def c1 (async/chan))
(def c2 (async/chan))

(def out
  (async/thread
    (loop [cs [c1 c2] vs []]
      (let [[v p] (async/alts!! cs)
            cs (filterv #(not= p %) cs)
            vs (conj vs v)]
        (if (seq cs)
          (recur cs vs)
          vs)))))

(async/>!! c1 :foo)
(async/>!! c2 :bar)

(async/<!! out)
;= [:foo :bar]

如果您希望从所有输入渠道获取所有值,然后在它们全部关闭时执行其他操作,则您需要使用async/merge

  

clojure.core.async /合并
  ([chs] [chs buf-or-n])
    获取源通道的集合并返回通道     包含从中获取的所有值。返回的频道将是     默认情况下不缓冲,或者可以提供buf-or-n。这个频道     将在所有源频道关闭后关闭。