2015-08-06 3 views
6

In gleicher Weise alt! warten eine n Kanäle einen Wert zu erhalten, ich suche für den idiomatischen Weg für alle n Kanäle warten, um einen Wert zu erhalten.für n Kanäle mit core.async Warten

Ich brauche dies, weil ich n go splocks auf asynchronen Aufgaben "spawn", und ich möchte wissen, wann sie alle fertig sind. Ich bin sicher, dass es einen sehr schönen Weg gibt, dies zu erreichen.

Antwort

4

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

+0

Dank! Ich denke 'merge' ist was ich brauche. – Blacksad

+0

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/

8

Verwenden core.asyncmap Funktion:

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

Dies sollte die richtige Antwort IMO sein, danke! – Lsdafjklsd