clojure.async:&#34; <! - not in(go ...)block“error - >

时间:2015-02-26 07:47:01

标签: clojure core.async

当我评估以下core.async clojurescript代码时,我收到一个错误:“未捕获错误:&lt;!不用于(go ...)block”

(let [chans [(chan)]]
  (go
   (doall (for [c chans]
     (let [x (<! c)]
       x)))))

我在这里做错了什么?它绝对看起来像&lt;!是在阻止。

2 个答案:

答案 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