代码不是从go块调用的,但是它可以在REPL中运行

Erw*_*ers 1 clojure goroutine clojurescript core.async figwheel

我有更新DOM的代码.new-recipe!调用API来获取新的配方字符串.update-recipe-state接下来在屏幕中更新此状态.最后我们打电话给update-transition-buttons.

(defn- add-listener-to-recipe-button! []
  "Listens to go button, creates a new recipe and displays it"
  (create-click-event-listener! (dommy/sel1 :#button-start)
                                #(go (new-recipe!)
                                     (<! (timeout 2000))
                                     (update-recipe-state!)
                                     (<! (timeout 2000))
                                     (update-transition-buttons! "onboarding"))))

;; define your app data so that it doesn't get over-written on reload
(defonce world
  (add-listener-to-recipe-button!))
Run Code Online (Sandbox Code Playgroud)

update-transition-buttons有步骤(利用超时代码之间的一些延迟在这里),如下所示:

(defn- update-transition-buttons! [recipe-name]
  "Updates the buttons with the transition names"
  (go
    ;; Split response in list of actions by splitting on the comma
    (let [response (<! (http/get (get-recipe-transitions-url recipe-name)))
          transition-names (clojure.string/split (:body response) ",")]
      (go (update-buttons! transition-names)
          (<! (timeout 2000))
          (js/console.log transition-names)
          (set-button-event-handlers! transition-names)))))
Run Code Online (Sandbox Code Playgroud)

所以它将响应拆分为一个字符串.updates-buttons通过添加一些按钮来更改页面上的状态(这是可见的).再次出现超时,然后我想将事件处理程序添加到按钮.这是它出错的地方.

创建事件侦听器(也包含a console.log)的例程如下所示:

(defn- listen-to-transition-button! [name]
  "Creates click event listener on button (button HTML ID should be name)"
  (do (js/console.log (str "Listening to " name))
    (let [name-without-spaces (clojure.string/replace name " " "")
          button (dommy/sel1 (keyword (str "#" name-without-spaces)))
          action #(do (perform-action! name)
                      (update-recipe-state!))]
      (create-click-event-listener! button action))))

(defn- set-button-event-handlers! [names]
  "Creates click event listeners on the buttons (button ID should be name)"
  (map listen-to-transition-button! names))
Run Code Online (Sandbox Code Playgroud)

您再次看到console.log传递的每个元素都应该发生的消息.我在Firefox控制台中获得的输出是:

[第一次服务]
[下一次服务]
[显示步骤列表]:["Step1","Step2","Step3"]

我的期望是:

[第一次服务]
[下一个服务被叫]
[显示步骤列表]:["Step1","Step2","Step3"]
听Step1
听Step2
听Step3

因此,由于某种原因,不会添加事件处理程序(依赖于之前步骤中生成的HTML),并且console.log不会显示消息.

当我从REPL 调用相同的代码时,我确实看到了输出,即:

repl =>(set-button-event-handlers!["Step1","Step2","Step3"])
(#object [Object [object Object]] #object [Object [object Object]] #object [Object [ object object]])

控制台输出是:

听Step1
听Step2
听Step3

为什么可以set-button-event-handlers!从REPL中调用,但之后不能在update-transition-buttons方法中调用update-buttons

lee*_*ski 6

看起来问题在这里:

(map listen-to-transition-button! names)
Run Code Online (Sandbox Code Playgroud)

set-button-event-handlers!

它创建了一个懒惰的seq,并且元素在代码中的某个地方(从未发生过)使用之前不会被实现,但是当你在repl中调用它时,它完全被实现为显示输出中的所有元素.尝试将此行更改为:

(doall (map listen-to-transition-button! names))
Run Code Online (Sandbox Code Playgroud)