What is the idiomatic way of waiting for a Clojure async channel?
这是代码的当前版本,非常简单。 它启动10个go例程,每个例程向该通道添加10条消息。 另一端是一个while true循环,该循环读取通道并每500 ms超时一次。
我正在考虑有更好的东西。 我认为while真正的循环可以用recur代替,在该循环中,它将读取通道,并在每次成功读取后返回以再次读取它。 如果发生超时,它将终止执行。
我有两个问题:
-这是正确的方法吗?
-如何使用惯用的Clojure实施
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | (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!")))))))) |
这是一种非常常见的方法,因此回答第一个问题,我会说"是"。 core.async提供了一些便利,可能会使它变得更加像偶像了(尽管实际上是这样):
-
优先于
(go (while true ...)) 或(go (loop ...)) 使用go-loop -
优先于
(let [[result channel]] (alts! ...)) 使用alt!