Clojurescript - 未捕获错误:<! - 不在(go ...)块中使用

时间:2015-08-16 17:09:56

标签: clojurescript core.async

我在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正确使用。

1 个答案:

答案 0 :(得分:2)

go宏将获取它所提供的正文,并将所有<!alt!>!调用转换为状态机。但它不会走进功能:

couldn't use for loop in go block of core.async?

  

通过在函数边界处停止转换,我的意思是:go块占用它的主体并将其转换为状态机。对<! >!alts!(以及其他一些)的每次调用都被视为状态机转换,其中块的执行可以暂停。在每个点上,机器变成回调并连接到通道。当此宏到达fn表单时,它将停止翻译。因此,您只能从go块内部调用<!,而不是在代码块内的函数内部。

     

这是core.async魔力的一部分。没有go宏,core.async代码看起来很像其他语言中的回调地狱。