Clojure 对于core.async通道是拉而不是推?

Clojure 对于core.async通道是拉而不是推?,clojure,core.async,Clojure,Core.async,我想知道为什么core.async通道中的数据是由无止境循环中的拉机制检索的。例如: user=> (def c (chan 1)) #'user/c user=> (go-loop [] (let [x (<! c)] (println "Got a value in this loop:" x)) (recur)) #<ManyToManyChannel clojure.core.async.impl.ch

我想知道为什么core.async通道中的数据是由无止境循环中的拉机制检索的。例如:

user=> (def c (chan 1))
#'user/c

user=> (go-loop []
         (let [x (<! c)]
           (println "Got a value in this loop:" x))
         (recur))

#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@30df0e27>
user=>(def c(通道1))
#'用户/c
用户=>(转到循环[]
(让[x](
参考:

为什么没有一个我可以挂接的推送机制?或者为什么这样的循环没有core.async订阅服务器的一些实现细节?
我认为让一个机制无休止地运行是非常消耗cpu的。不是这样吗?

核心的docstring.async/go说:

异步执行主体,立即返回到 调用线程。此外,对!和alt!/alts!的任何可见调用! 身体内的通道操作将通过以下方式阻止(如有必要) “停止”调用线程,而不是捆绑操作系统线程(或 在ClojureScript)中的唯一JS线程。完成 操作后,身体将恢复。 返回一个通道,该通道将在 完成


如果
go
在等待队列上的新消息时没有停止,那么循环确实会对CPU造成很大的浪费。但是,当go循环到达
时,它将停止线程,并且只有在可以从队列中获取值时才会恢复。

“Clojure for the brave and true”有一个精彩的章节详细解释了这一点。