Clojure async - 频道中项目的顺序

Clojure async - Order of items in a channel

我在理解以下代码示例的输出时遇到一些困难。

(def ch (a/chan 1))

(a/go-loop []
  (Thread/sleep 1000)
  (a/onto-chan ch [1 2 3 4 5] false)
  (recur))

(a/go-loop []
  (Thread/sleep 500)
  (let [val (a/<! ch)]
    (println val))
  (recur))

我希望看到的是打印到 REPL 的每个数字之间有 500 毫秒的延迟,在另一个范围开始打印之前按顺序接收数字 1-5。

但是,当将 Thread/sleep 引入从通道读取的 go-block 时,数字似乎交错了。我的印象是,从频道中检索项目的顺序与将它们放入频道的顺序相同?

有什么我遗漏的吗?

onto-chan 异步执行。您的第一个 go-loop 的每次执行基本上都会启动一个新进程,将值并行放入通道。请注意文档,其中说明 Returns a channel which will close after the items are copied.

如果您等待 onto-chan 完成,您会得到预期的结果:

(def ch (async/chan 1))

(async/go-loop []
  (Thread/sleep 1000)
  (async/<! (async/onto-chan ch [1 2 3 4 5] false))
  (recur))

(async/go-loop []
  (Thread/sleep 500)
  (when-let [val (async/<! ch)]
    (println val)
    (recur)))