我想知道为什么来自core.async通道的数据是由无限循环中的pull机制检索的。例如:
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>
参考:https://clojuredocs.org/clojure.core.async/go-loop#example-542c88e3e4b05f4d257a297b
为什么没有可以挂钩的推送机制?或者为什么不是这样的循环core.async订阅者的一些实现细节? 我认为拥有一个无休止地运行的机制是非常麻烦的。这不是这种情况吗?
答案 0 :(得分:2)
core.async/go
的文档字符串说:
异步执行正文,立即返回到 调用线程。此外,任何可见的呼叫!和alt!/ alts! 身体内的通道操作将阻止(如有必要) &#39;停车&#39;调用线程而不是绑定OS线程(或 在ClojureScript中唯一的JS线程)。完成后 手术后,身体将恢复。 返回一个通道,它将在何时接收正文的结果 完成
如果go
在等待队列中的新消息时没有停放,那么循环在CPU上确实非常浪费。但是,当go循环到达<!
时,它将停放线程,并且只有在可以从队列中获取值时才会恢复。