core-async

2019-01-24T16:24:02.087300Z

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?

2019-01-24T16:46:02.087500Z

clojure.core.async/merge

2019-01-24T16:56:25.088200Z

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

bertofer 2019-01-24T16:58:18.088600Z

I think you could use core.async/map (https://clojuredocs.org/clojure.core.async/map)

2019-01-24T16:59:19.088800Z

Oh, I bet you're right!

2019-01-24T16:59:58.089100Z

Yay!

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

๐Ÿ‘Œ 1
ghadi 2019-01-24T17:49:35.090100Z

core.async/map is deprecated @bmaddy @bertofer

ghadi 2019-01-24T17:49:49.090500Z

in favor of transducers on the channel

alexmiller 2019-01-24T17:50:09.091Z

no, itโ€™s not

ghadi 2019-01-24T17:50:10.091100Z

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