What is the idiomatic way to wait for a Clojure asynchronous channel?

This is the current version of the code that does a very simple job. It starts 10 moves, and each procedure adds 10 messages to the channel. The other end is a true loop that reads the channel and latency every 500 ms.

I was thinking of something better. I think that while the true loop can be replaced by recur, where it reads the channel, and after each successful read, it returns to read it again. If a timeout occurs, it simply terminates.

I have two questions: - Is this the right approach? - how to implement it using idiomatic Clojure

(defn -main [& args] (let [c (async/chan)] (doseq [i (range 10)] (async/go (doseq [j (range 10)] (Thread/sleep (rand-int 1000)) (async/>! c (str i " :: " j))))) (while true (async/<!! (async/go (let [[result source] (async/alts! [c (async/timeout 500)])] (if (= source c) (println "Got a value!" result) (println "Timeout!")))))))) 
+5
source share
1 answer

This is a very common approach, so to answer your first question, I would say yes. There are several amenities offered by core.async that could make it a little more idomal (though it really is as it is):

  • use go-loop instead of (go (while true ...)) or (go (loop ...))
  • use alt! instead of (let [[result channel]] (alts! ...))
+7
source

Source: https://habr.com/ru/post/1206827/


All Articles