简体   繁体   English

未从go块调用代码,但可在REPL中使用

[英]Code not called from go block, but it works from REPL

I have code that updates the DOM. 我有更新DOM的代码。 new-recipe! calls an API to get a new recipe string. 调用API以获取新的配方字符串。 update-recipe-state next updates this state in the screen. 接下来, update-recipe-state state会在屏幕上更新此状态。 Finally we have a call to update-transition-buttons . 最后,我们调用了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!))

The update-transition-buttons has some delays between the steps (using the timeout code here ) looks as follows: 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)))))

So it splits the response to a string. 因此它将响应拆分为一个字符串。 updates-buttons changes state on the page by adding some buttons (this is visible). updates-buttons通过添加一些updates-buttons更改页面上的状态(可见)。 Again there is a timeout, and then I want to add the event handlers to the buttons . 再次有一个超时,然后我想将事件处理程序添加到button This is where it goes wrong. 这就是问题所在。

The routine to create event listeners (which also contain a console.log ) look as follows: 创建事件监听器的例程(还包含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))

Again you see a console.log message that should happen for each elements that is passed. 再次,您看到应该对传递的每个元素发生console.log消息。 The output I get in the Firefox console is: 我在Firefox控制台中得到的输出是:

[FIRST SERVICE CALLED] [第一服务呼叫]
[NEXT SERVICE CALLED] [下一个服务呼叫]
[DISPLAY LIST OF STEPS]: ["Step1", "Step2", "Step3"] [步骤的显示列表]:[“ Step1”,“ Step2”,“ Step3”]

What I expect is: 我期望的是:

[FIRST SERVICE CALLED] [第一服务呼叫]
[NEXT SERVICE CALLED] [下一个服务呼叫]
[DISPLAY LIST OF STEPS]: ["Step1", "Step2", "Step3"] [步骤的显示列表]:[“ Step1”,“ Step2”,“ Step3”]
Listening to Step1 聆听Step1
Listening to Step2 聆听Step2
Listening to Step3 聆听Step3

So the event handlers (which depend on the HTML generated in the step before) are not added for some reason and the console.log message is not displayed. 因此,由于某种原因,未添加事件处理程序(取决于前面步骤中生成的HTML),并且不会显示console.log消息。

When I call the same code from the REPL I do see the output, ie: 当我从REPL调用相同的代码时 ,我确实看到了输出,即:

repl=> (set-button-event-handlers! ["Step1","Step2", "Step3"]) repl =>(设置按钮事件处理程序![“ Step1”,“ Step2”,“ Step3”])
(#object[Object [object Object]] #object[Object [object Object]] #object[Object [object Object]]) (#object [Object [object Object]] #object [Object [object Object]] #object [Object [object Object]])

And the console output is: 控制台输出为:

Listening to Step1 聆听Step1
Listening to Step2 聆听Step2
Listening to Step3 聆听Step3

Why can set-button-event-handlers! 为什么可以set-button-event-handlers! be called from the REPL, but not in the update-transition-buttons method after update-buttons ? 从REPL调用,而不是在update-transition-buttons后,方法update-buttons

looks like the problem is here: 看起来问题出在这里:

(map listen-to-transition-button! names)

in set-button-event-handlers! set-button-event-handlers!

it creates a lazy seq, and elements won't be realized until their usage somewhere in code (which never happens), but when you call it in repl, it is being fully realized to show all the elements in output. 它创建了一个惰性序列,直到元素在代码中的某个地方使用(永远不会发生)时,这些元素才会被实现,但是当您在repl中调用它时,它将被完全实现以显示输出中的所有元素。 Try changing this line to: 尝试将此行更改为:

(doall (map listen-to-transition-button! names))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM