【问题标题】:What is the idiomatic way of waiting for a Clojure async channel?等待 Clojure 异步通道的惯用方式是什么?
【发布时间】:2014-11-13 19:02:14
【问题描述】:

这是执行非常简单的代码的当前版本。它启动 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!"))))))))

【问题讨论】:

  • 我认为在 core.async 代码中对Thread/sleep 的任何使用总是是一种代码异味——你无缘无故地填满了你的线程池。想不出&lt;!&lt;!! 来自timeout 的任何场景都不会更合适。
  • ...而且,是的,我同意从频道循环/重复读取是惯用的。

标签: clojure core.async


【解决方案1】:

这是一种非常常见的方法,所以要回答您的第一个问题,我会说是的。 core.async 提供了一些便利,可以使它更符合规范(尽管它的方式真的很好):

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 2011-03-07
    • 2021-05-08
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多