clojure.async: "<! not in (go ...) block" 错误
clojure.async: "<! not in (go ...) block" error
当我评估以下 core.async clojurescript 代码时出现错误:"Uncaught Error: <! used not in (go ...) block"
(let [chans [(chan)]]
(go
(doall (for [c chans]
(let [x (<! c)]
x)))))
我在这里做错了什么?它绝对看起来像
因为 go
块不能跨越函数边界,所以在很多情况下我倾向于使用 loop/recur。 (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)
...))
来自文档:
Completes at most one of several channel operations. Must be called
inside a (go ...) block. ports is a vector of channel endpoints,
which can be either a channel to take from or a vector of
[channel-to-put-to val-to-put], in any combination. Takes will be
made as if by !. Unless
the :priority option is true, if more than one port operation is
ready a non-deterministic choice will be made. If no operation is
ready and a :default value is supplied, [default-val :default] will
be returned, otherwise alts! will park until the first operation to
become ready completes. Returns [val port] of the completed
operation, where val is the value taken for takes, and a
boolean (true unless already closed, as per put!) for put
证明ref
当我评估以下 core.async clojurescript 代码时出现错误:"Uncaught Error: <! used not in (go ...) block"
(let [chans [(chan)]]
(go
(doall (for [c chans]
(let [x (<! c)]
x)))))
我在这里做错了什么?它绝对看起来像
因为 go
块不能跨越函数边界,所以在很多情况下我倾向于使用 loop/recur。 (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)
...))
来自文档:
Completes at most one of several channel operations. Must be called inside a (go ...) block. ports is a vector of channel endpoints, which can be either a channel to take from or a vector of [channel-to-put-to val-to-put], in any combination. Takes will be made as if by !. Unless the :priority option is true, if more than one port operation is ready a non-deterministic choice will be made. If no operation is ready and a :default value is supplied, [default-val :default] will be returned, otherwise alts! will park until the first operation to become ready completes. Returns [val port] of the completed operation, where val is the value taken for takes, and a boolean (true unless already closed, as per put!) for put
证明ref