clojure.async:"<! not in (go ...) block"错误



当我评估以下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!)

倍增参考

最新更新