等待Clojure异步通道的惯用方法是什么?

Ist*_*van 5 clojure core.async

这是代码的当前版本,它可以完成非常简单的工作.它启动10个例程,每个例程向通道添加10条消息.另一端是一个真正的循环,读取通道并每500毫秒超时.

我在想有更好的东西.我认为while true循环可以替换为recur,其中它读取通道,并且在每次成功读取之后它会再次读取它.如果发生超时,它只会终止执行.

我有两个问题: - 这是正确的方法吗? - 如何使用惯用的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!"))))))))
Run Code Online (Sandbox Code Playgroud)

Art*_*ldt 7

这是一种非常常见的方法,所以要回答你的第一个问题,我会说是的.core.async提供了一些便利,可以使它更具有一些风格(尽管它的确非常好):

  • go-loop优先使用(go (while true ...))(go (loop ...))
  • 使用alt!优先于(let [[result channel]] (alts! ...))