Clojurescript - Uncaught Error: <! used not in (go ...) block
Clojurescript - Uncaught Error: <! used not in (go ...) block
我在 Clojurescript 中,并尝试使用 core.async
从本机 Javascript 函数中获取结果(我在浏览器中),并有条件地将其集成到地图中。
我有一个包装本机浏览器调用的函数(受 Timothy Baldridge's talk on core.async 启发,感兴趣的人大约需要 34 分钟):
(defn geolocation []
(let [c (chan)
cb (fn [e] (put! c (js->clj e)))]
(if (exists? js/navigator.geolocation)
(.getCurrentPosition js/navigator.geolocation. cb cb)
(put! c {:error "Geolocation is not supported"}))
c))
我可以这样使用它:
;; this works
(go (.log js/console "RES1 -" (<! (geolocation))))
;; this too (not sure how to print it though)
(go (println "RES2 - " (-> {}
(assoc :test (<! (geolocation))))))
;; this fails... why ?
(go (println "RES3 - " (-> {}
(#(when true
(assoc % :test (<! (geolocation))))))))
最后一个示例因错误而失败:Uncaught Error: <! used not in (go ...) block
,尽管我认为我使用的是相同类型的结构。
我做错了什么?
注意 :我从 :require-macro
指令中正确地要求它,like described here.
go
宏将采用给定的主体并将所有 <!
和 alt!
以及 >!
调用转换为状态机。但是它不会进入功能:
couldn't use for loop in go block of core.async?
By stops translation at function boundaries, I mean this: the go block takes its body and translates it into a state-machine. Each call to <!
>!
or alts!
(and a few others) are considered state machine transitions where the execution of the block can pause. At each of those points the machine is turned into a callback and attached to the channel. When this macro reaches a fn form it stops translating. So you can only make calls to <!
from inside a go block, not inside a function inside a code block.
This is part of the magic of core.async
. Without the go
macro, core.async code would look a lot like callback-hell in other langauges.
我在 Clojurescript 中,并尝试使用 core.async
从本机 Javascript 函数中获取结果(我在浏览器中),并有条件地将其集成到地图中。
我有一个包装本机浏览器调用的函数(受 Timothy Baldridge's talk on core.async 启发,感兴趣的人大约需要 34 分钟):
(defn geolocation []
(let [c (chan)
cb (fn [e] (put! c (js->clj e)))]
(if (exists? js/navigator.geolocation)
(.getCurrentPosition js/navigator.geolocation. cb cb)
(put! c {:error "Geolocation is not supported"}))
c))
我可以这样使用它:
;; this works
(go (.log js/console "RES1 -" (<! (geolocation))))
;; this too (not sure how to print it though)
(go (println "RES2 - " (-> {}
(assoc :test (<! (geolocation))))))
;; this fails... why ?
(go (println "RES3 - " (-> {}
(#(when true
(assoc % :test (<! (geolocation))))))))
最后一个示例因错误而失败:Uncaught Error: <! used not in (go ...) block
,尽管我认为我使用的是相同类型的结构。
我做错了什么?
注意 :我从 :require-macro
指令中正确地要求它,like described here.
go
宏将采用给定的主体并将所有 <!
和 alt!
以及 >!
调用转换为状态机。但是它不会进入功能:
couldn't use for loop in go block of core.async?
By stops translation at function boundaries, I mean this: the go block takes its body and translates it into a state-machine. Each call to
<!
>!
oralts!
(and a few others) are considered state machine transitions where the execution of the block can pause. At each of those points the machine is turned into a callback and attached to the channel. When this macro reaches a fn form it stops translating. So you can only make calls to<!
from inside a go block, not inside a function inside a code block.This is part of the magic of
core.async
. Without thego
macro, core.async code would look a lot like callback-hell in other langauges.