关于clojure:pull而不是push for core.async通道?

pull instead of push for core.async channels?

我想知道为什么core.async通道中的数据通过循环机制中的拉取机制进行检索。 例如:

1
2
3
4
5
6
7
8
9
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订户的实现细节?
我认为拥有不断运行的机制非常消耗CPU。 不是这样吗?


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

Asynchronously executes the body, returning immediately to the
calling thread. Additionally, any visible calls to ! and alt!/alts!
channel operations within the body will block (if necessary) by
'parking' the calling thread rather than tying up an OS thread (or
the only JS thread when in ClojureScript). Upon completion of the
operation, the body will be resumed.
Returns a channel which will receive the result of the body when
completed

如果go在等待队列中的新消息时没有停放,则循环确实在CPU上非常浪费。 但是,当go循环到达时,它将驻留线程,并且仅在可从队列中获取值时才继续执行。