拉而不是推送core.async频道?

时间:2015-05-21 08:47:18

标签: clojure core.async

我想知道为什么来自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订阅者的一些实现细节? 我认为拥有一个无休止地运行的机制是非常麻烦的。这不是这种情况吗?

1 个答案:

答案 0 :(得分:2)

core.async/go的文档字符串说:

  

异步执行正文,立即返回到   调用线程。此外,任何可见的呼叫!和alt!/ alts!   身体内的通道操作将阻止(如有必要)   &#39;停车&#39;调用线程而不是绑定OS线程(或   在ClojureScript中唯一的JS线程)。完成后   手术后,身体将恢复。    返回一个通道,它将在何时接收正文的结果   完成

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