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

欢迎!有关此功能的工作原理,请参阅关于页面以获取更多信息。

+1 点赞
core.async

`
(<! (go

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

`

产出:#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))

而成功的情况下,在 cljs.core/PersistentVector 之前有一个普通的 JS new 关键字

  (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))
...