Fork me on GitHub
#core-async
<
2019-01-24
>
bmaddy16:01:02

How do I convert a collection of channels that will contain only one value (response from a network request) to a collection of those values, while maintaining order?

;; Specifically, I have this
[ch1 ch2 ch3 ...]
;; and want this
[(<! ch1) (<! ch2) (<! ch3) ...]
My first thought was something like (map #(<! %) chs), but I don't think the containing go block will work across the function border. Eventually, a coworker came up with this, but it really seems like there should be an easier way that we're not thinking of.
(a/go-loop [acc [] chs chs]
  (if (seq chs)
    (let [ret (<! (first chs))]
      (recur (conj acc ret) (rest chs)))
    acc))
Is there a better way to do this?

hiredman16:01:02

clojure.core.async/merge

bmaddy16:01:25

I looked at that, but it uses alts!, so order is lost.

bmaddy16:01:19

Oh, I bet you're right!

bmaddy16:01:58

Yay!

(<!! (a/map vector [(a/go (Thread/sleep 1000) 1) (a/go 2)]))
[1 2]
Thanks!

👌 5
ghadi17:01:35

core.async/map is deprecated @bmaddy @bertofer

ghadi17:01:49

in favor of transducers on the channel

ghadi17:01:10

whoops, no it isn't: that's map< and map>