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

等待Clojure异步通道的惯用方式是什么?,clojure,core.async,Clojure,Core.async,这是代码的当前版本,可以完成非常简单的工作。它启动10个go例程,每个例程向通道添加10条消息。另一端是一个while-true循环,它读取通道并每500毫秒超时一次 我在考虑买点更好的。我认为while-true循环可以被一个循环所取代,在这个循环中,它读取通道,并且在每次成功读取之后,它都返回来再次读取通道。如果发生超时,它将终止执行 我有两个问题: -这是正确的方法吗? -如何使用惯用Clojure实现它 (defn -main [& args] (let [c (async/

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

我在考虑买点更好的。我认为while-true循环可以被一个循环所取代,在这个循环中,它读取通道,并且在每次成功读取之后,它都返回来再次读取通道。如果发生超时,它将终止执行

我有两个问题: -这是正确的方法吗? -如何使用惯用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!"))))))))
(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中调用
线程/睡眠
的任何用法。异步代码总是一种代码味道——你在毫无理由地填充线程池。想不出任何情况下
超时
读取会更合适……是的,我同意从通道读取循环/重复将是惯用的。