等待Clojure异步通道的惯用方式是什么?
这是代码的当前版本,可以完成非常简单的工作。它启动10个go例程,每个例程向通道添加10条消息。另一端是一个while-true循环,它读取通道并每500毫秒超时一次 我在考虑买点更好的。我认为while-true循环可以被一个循环所取代,在这个循环中,它读取通道,并且在每次成功读取之后,它都返回来再次读取通道。如果发生超时,它将终止执行 我有两个问题: -这是正确的方法吗? -如何使用惯用Clojure实现它等待Clojure异步通道的惯用方式是什么?,clojure,core.async,Clojure,Core.async,这是代码的当前版本,可以完成非常简单的工作。它启动10个go例程,每个例程向通道添加10条消息。另一端是一个while-true循环,它读取通道并每500毫秒超时一次 我在考虑买点更好的。我认为while-true循环可以被一个循环所取代,在这个循环中,它读取通道,并且在每次成功读取之后,它都返回来再次读取通道。如果发生超时,它将终止执行 我有两个问题: -这是正确的方法吗? -如何使用惯用Clojure实现它 (defn -main [& args] (let [c (async/
(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!"))))))))
(defn-main[&args]
(让[c(async/chan)]
(doseq[i(范围10)]
(异步/去
(doseq[j(范围10)]
(线程/休眠(兰特int 1000))
(async/>!c(str i):“j()()()))
(虽然是真的
(async/这是一种非常常见的方法,所以要回答您的第一个问题,我会说是的。core.async提供了一些便利,可以让它更具idomatic(尽管它确实很好):
- 使用
go-loop
优先于(go(while true…)
或(go(loop…)
- 优先于
(让[[结果频道]](alts!…)使用)
我会在core中调用线程/睡眠
的任何用法。异步代码总是一种代码味道——你在毫无理由地填充线程池。想不出任何情况下或从超时
读取会更合适……是的,我同意从通道读取循环/重复将是惯用的。