2024 Clojure 状态调查! 中分享您的想法。

欢迎!请访问 关于 页面以了解更多关于这一机制的详细信息。

+1
core.async

`
(<! (go

  (let [new 42]
    [new])))

`

yields: #object(link: TypeError TypeError: 42.call is not a function)

new 没有得到正确的处理。

2 个答案

0
参考: https://clojure.atlassian.net/browse/ASYNC-176 (由 alex+import 报告)
0

我对这个问题没有答案。我遇到相同的问题并且做了一些调查,我想在这里分享,以帮助查看此问题的任何人。我发现这个问题与创建 cljs.core/PersistentVector 有关。以下是我的示例

(require '[cljs.core.async :refer [go <! chan put!]])

(def c (chan))

(put! c {:hi "here"})

;; This fails
(go
  (let [{:keys [new] :as msg} (<! c)]
    (js/console.log [:msg-received msg])))
;; ioc_helpers.cljs:50 Uncaught TypeError: inst_25288.call is not a function
;; at switch__20329__auto__ (eval at figwheel$repl$eval_javascript_STAR__STAR_ (repl.cljc:364), <anonymous>:86:29)
;; at eval (eval at figwheel$repl$eval_javascript_STAR__STAR_ (repl.cljc:364), <anonymous>:166:51)
;; at mini_reframe$app$state_machine__20330__auto____1 (eval at figwheel$repl$eval_javascript_STAR__STAR_ (repl.cljc:364), <anonymous>:188:4)
;; at mini_reframe$app$state_machine__20330__auto__ (eval at figwheel$repl$eval_javascript_STAR__STAR_ (repl.cljc:364), <anonymous>:204:57)
;; at cljs$core$async$impl$ioc_helpers$run_state_machine (ioc_helpers.cljs:43)
;; at cljs$core$async$impl$ioc_helpers$run_state_machine_wrapped (ioc_helpers.cljs:47)
;; at eval (eval at figwheel$repl$eval_javascript_STAR__STAR_ (repl.cljc:364), <anonymous>:218:67)
;; at cljs$core$async$impl$dispatch$process_messages (dispatch.cljs:27)
;; at MessagePort.channel.port1.onmessage (nexttick.js:218)

(put! c {:hi "here"})

;; All the below cases work
(go
  (let [{:keys [a] :as msg} (<! c)]
    (js/console.log [:msg-received msg])))
;; [:msg-received {:hi "here"}]

(put! c {:hi "here"})

(go
  (let [msg (<! c)]
    (js/console.log [:msg-received msg])))
;; [:msg-received {:hi "here"}]

(put! c {:hi "here"})

(go
  (let [{:keys [new] :as msg} (<! c)]
    (js/console.log msg)))
;; {:hi "here"}

(put! c {:hi "here"})

(defn receive-msg [msg]
  (js/console.log [:msg-received msg]))

(go
  (let [{:keys [new] :as msg} (<! c)]
    (receive-msg msg)))
;; [:msg-received {:hi "here"}]

当我比较 macroexpand-1 的结果时,我发现失败的情况中,new 的 let 绑定似乎遮蔽了 JS 的 new 关键字,如下面的 inst_23688 符号所示,在 cljs.core/PersistentVector 之前

  (macroexpand-1
    '(go
       (let [{:keys [new] :as msg} (<! c)]
         (js/console.log [:msg-received msg]))))
  => ...
      (clojure.core/let
           [inst_23687
            (clojure.core/aget state_23694 2)
            inst_23688
            (cljs.core/get inst_23687 :new)
            inst_23689
            (. cljs.core/PersistentVector -EMPTY-NODE)
            inst_23690
            (js* "[~{},~{}]" :msg-received inst_23687)
            inst_23691
            (inst_23688
             cljs.core/PersistentVector
             nil
             2
             5
             inst_23689
             inst_23690
             nil)
            inst_23692
            (js/console.log inst_23691)
            state_23694
            state_23694]
           (cljs.core.async.impl.ioc-helpers/return-chan
            state_23694
            inst_23692))

而在成功的情况下,new JS 关键字在 cljs.core/PersistentVector 之前是平凡的

  (macroexpand-1
    '(go
       (let [{:keys [a] :as msg} (<! c)]
         (js/console.log [:msg-received msg]))))
=> ...
(clojure.core/let
           [inst_24256
            (clojure.core/aget state_24263 2)
            inst_24257
            (cljs.core/get inst_24256 :a)
            inst_24258
            (. cljs.core/PersistentVector -EMPTY-NODE)
            inst_24259
            (js* "[~{},~{}]" :msg-received inst_24256)
            inst_24260
            (new cljs.core/PersistentVector nil 2 5 inst_24258 inst_24259 nil)
            inst_24261
            (js/console.log inst_24260)
            state_24263
            (cljs.core.async.impl.ioc-macros/aset-all!
             state_24263
             8
             inst_24257)]
           (cljs.core.async.impl.ioc-helpers/return-chan
            state_24263
            inst_24261))
...