当我评估以下core.async clojurescript代码时,我收到一个错误:“未捕获错误:<!不用于(go ...)block”
(let [chans [(chan)]]
(go
(doall (for [c chans]
(let [x (<! c)]
x)))))
我在这里做错了什么?它绝对看起来像&lt;!是在阻止。
答案 0 :(得分:5)
因为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]
答案 1 :(得分:1)
为什么不使用alts!
中的Core.Async
?
此功能可让您收听多个频道,并了解您从每个数据中读取的频道。
例如:
(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是通道端点的向量, 它可以是一个通道,也可以是一个矢量 [任意组合的通道 - 放置到val-to-put]。需要 就好像是!除非 如果有多个端口操作,则:priority选项为true 准备好了一个非确定性的选择。如果没有操作 ready和a:提供默认值,[default-val:default]将 退回,否则等!将停放到第一次操作到 准备完成。返回已完成的[val port] 操作,其中val是取得的值,和a boolean(true,除非已经关闭,按照put!)for put
Doumentation ref