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.