当我评估以下core.async clojudescript代码时,我得到一个错误:"未捕获错误:<!未在(go…)块中使用"
(let [chans [(chan)]]
(go
(doall (for [c chans]
(let [x (<! c)]
x)))))
我在这里做错了什么?它看起来绝对像<!正在进行中。
因为go
块不能跨越函数边界,所以在很多情况下,我倾向于循环/重复。(go (loop
模式是如此常见,以至于它在core.async中具有短手形式,在这种情况下很有用:
user> (require '[clojure.core.async :as async])
user> (async/<!! (let [chans [(async/chan) (async/chan) (async/chan)]]
(doseq [c chans]
(async/go (async/>! c 42)))
(async/go-loop [[f & r] chans result []]
(if f
(recur r (conj result (async/<! f)))
result))))
[42 42 42]
为什么不从Core.Async
使用alts!
?
此功能允许您在多个频道上收听,并知道您从哪个频道读取每个数据。
例如:
(let [chans [(chan)]]
(go
(let [[data ch] (alts! chans)]
data)))))
你也可以询问信道来源:
...
(let [slow-chan (chan)
fast-chan (chan)
[data ch] (alts! [slow-chan fast-chan])]
(when (= ch slow-chan)
...))
从文档:
最多完成几个通道操作中的一个。必须调用在一个(去…)街区内。ports是信道端点的向量,其可以是要获取的通道,也可以是〔channel to put to val to put〕,任意组合。Takes will做得像是被!。除非如果有多个端口操作,则:priority选项为true准备好了,将做出不确定的选择。如果没有操作准备就绪,并且提供了一个:默认值,[默认值:默认值]将返回,否则alts!将停车,直到第一次操作准备就绪完成。返回已完成的的[val port]运算,其中val是take的取值put 的布尔值(true,除非已经关闭,根据put!)
倍增参考