This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-12-31
Channels
- # adventofcode (4)
- # ai (1)
- # announcements (13)
- # babashka (1)
- # beginners (42)
- # calva (15)
- # chlorine-clover (28)
- # cider (7)
- # cljsrn (1)
- # clojure (3)
- # clojure-china (1)
- # clojure-dev (4)
- # clojure-europe (7)
- # clojure-losangeles (1)
- # clojure-nl (3)
- # clojure-nlp (2)
- # clojure-sweden (12)
- # clojure-uk (2)
- # clojurescript (30)
- # code-reviews (36)
- # core-async (5)
- # cursive (10)
- # data-science (1)
- # datalevin (1)
- # fulcro (11)
- # introduce-yourself (1)
- # lsp (10)
- # malli (7)
- # minecraft (24)
- # missionary (10)
- # monads (6)
- # nrepl (4)
- # off-topic (11)
- # portal (4)
- # rdf (1)
- # reagent (3)
- # releases (4)
- # shadow-cljs (4)
- # spacemacs (4)
hi there. I use cljs.core.async
and have a question.
Next code is working well:
(go
(let [a (<p! (return-promise-fn "a"))
b (<p! (return-promise-fn "b"))
c (<p! (return-promise-fn "c"))
result (into [] a b c)]
(prn result))) ;; I can get results of promise
I want to change this to like next:
(let [result (map
(fn [v] (go (<p! (return-promise-fn v))))
["a" "b" "c"])]
(prn result)) ;; I cannot get results of promise
but this code doesn't work as I expect.
I understand the occasion is that result
is outside the go
block, but I have no idea what to fix this problem.go blocks are not monadic values, cant be chained like promises go blocks are more like light-weight threads that can communicate/coordinate via channels.
(defn promise [v]
(js/Promise.resolve v))
(def collect-chan (chan 1))
;; launch a go block for collecting results from collect-chan
(go-loop [result []
item (<! collect-chan)]
;; item is not nil as long as channel is open
(if item
(recur (conj result item)
(<! collect-chan))
;; when channel is close will print collected values
(println "collected:" result)))
;; launch n go blocks, one for each promise
;; wait for promise result and then send result to collect-chan
(doseq [p (map promise [1 2 3 4 5])]
(go (let [prom-result (<p! p)]
(println "send" prom-result)
(>! collect-chan prom-result))))
;; close the chan so that go-loop chan break the loop
(close! collect-chan)
dont take my example as a good practice, just showing the idea of how it works:laughing:
also go blocks behave like channel too
(let [ps (map (fn [v]
(go (<p! (promise v))))
["a" "b" "c"])]
(go-loop [result []
[p & ps :as pps] ps]
(if (seq pps)
(recur (conj result (<! p))
ps)
(prn result))))