简体   繁体   English

使用core.async等待n个通道

[英]Waiting for n channels with core.async

In the same way alt! 以同样的方式alt! waits for one of n channels to get a value, I'm looking for the idiomatic way to wait for all n channels to get a value. 为n个信道的一个等待获取值,我正在寻找的习惯的方法来等待所有 n渠道得到的值。

I need this because I "spawn" n go blocks to work on async tasks, and I want to know when they are all done. 我需要这个,因为我“生成”n块来处理异步任务,我想知道它们何时完成。 I'm sure there is a very beautiful way to achieve this. 我确信有一种非常漂亮的方法来实现这一目标。

Use the core.async map function: 使用core.async map函数:

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

You can say (mapv #(async/<!! %) channels) . 你可以说(mapv #(async/<!! %) channels)

If you wanted to handle individual values as they arrive, and then do something special after the final channel produces a value, you can use exploit the fact that alts! 如果您希望在到达时处理单个值,然后在最终通道生成值后执行一些特殊操作,则可以使用利用的事实alts! / alts!! / alts!! take a vector of channels, and they are functions, not macros, so you can easily pass in dynamically constructed vectors. 采用一个通道向量,它们是函数,而不是宏,因此您可以轻松地传入动态构造的向量。

So, you can use alts!! 所以,你可以使用alts!! to wait on your initial collection of n channels, then use it again on the remaining channels etc. 等待你的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]

If instead you wanted to take all values from all the input channels and then do something else when they all close, you'd want to use async/merge : 如果您希望从所有输入通道中获取所有值,然后在它们全部关闭时执行其他操作,则您需要使用async/merge

clojure.core.async/merge clojure.core.async /合并
([chs] [chs buf-or-n]) ([chs] [chs buf-or-n])
Takes a collection of source channels and returns a channel which contains all values taken from them. 获取源通道的集合并返回包含从它们获取的所有值的通道。 The returned channel will be unbuffered by default, or a buf-or-n can be supplied. 默认情况下,返回的通道将是无缓冲的,或者可以提供buf-or-n。 The channel will close after all the source channels have closed. 所有源通道关闭后,通道将关闭。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM