Sie können (mapv #(async/<!! %) channels)
sagen.
Wenn Sie einzelne Werte zu handhaben wollten, wie sie ankommen, und dann etwas Besonderes tun nach dem letzten Kanal erzeugt einen Wert, können Sie die Tatsache ausnutzen verwenden, dass alts!
/alts!!
einen Vektor der Kanäle nehmen, und sie sind Funktionen, nicht Makros, so dass Sie dynamisch konstruierte Vektoren einfach übergeben können.
So können Sie alts!!
verwenden auf Ihre erste Sammlung von n Kanälen zu warten, dann wieder verwenden, um auf die verbleibenden Kanäle usw.
(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]
Wenn Sie stattdessen alle Werte von allen Eingangskanälen nehmen wollte und dann etwas anderes tun, wenn sie alle in der Nähe, dann würden Sie verwenden async/merge
wollen:
clojure.core.async/merge
([chs] [chs buf-or-n])
Takes a Sammlung von Quellkanälen und gibt einen Kanal zurück, der alle daraus entnommenen Werte enthält. Der zurückgegebene Kanal wird standardmäßig ungepuffert sein, oder ein Buf-oder-N kann geliefert werden. Der Kanal wird geschlossen, nachdem alle Quellkanäle geschlossen wurden. die
Dank! Ich denke 'merge' ist was ich brauche. – Blacksad
Großartig! NB. Ich habe gerade die einfachste Lösung hinzugefügt, um auf einen einzelnen Wert von jedem Kanal zu warten (im Gegensatz zu allen Werten, bevor alle Kanäle geschlossen werden), was '(mapv # (async/