代码不是从go块调用,但它的工作原理是REPL [英] Code not called from go block, but it works from REPL

查看:174
本文介绍了代码不是从go块调用,但它的工作原理是REPL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 添加监听器到配方按钮![] 
监听go按钮,创建一个新配方并显示它
(create-click-event-listener!(dommy / sel1: #button-start)
#(go(new-recipe!)
(< ;!(timeout 2000))
(update-recipe-state! !(timeout 2000))
(update-transition-buttons!onboarding))))

;定义你的应用程序数据,使它不会覆盖reload
(defonce world
(add-listener-to-recipe-button!))

update-transition-buttons 在步骤之间有一些延迟(使用超时代码< a href =https://gist.github.com/swannodette/5882703 =nofollow>此处)如下所示:

 (defn-update-transition-buttons![recipe-name] 
更新带有转换名称的按钮
(go
;; Split response in通过拆分逗号
的动作列表(let [response(< ;!(http / 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)))))

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



创建事件监听器的例程(它还包含一个 console.log )如下:

 (defn- listen-to-transition-button![name] 
监听器按钮(按钮HTML ID应该是名称)
(do(js / console.log(strListening to name))
(let [name-without-spaces(clojure.string /替换名称)
按钮(dommy / sel1(关键字(str#name-without-spaces)))
action#(do(perform-action!name)
(update-recipe-state!))]
(create-click-event-listener!button action))))

(defn- set-button-event-handlers! ]
在按钮上创建点击事件监听器(按钮ID应该是名称)
(map listen-to-transition-button!names))
/ pre>

同样你会看到一个 console.log 消息,应该对每个传递的元素发生。我在Firefox控制台中得到的输出是:


[第一个服务调用]

[下一个服务调用] br>
[显示步骤列表]:[Step1,Step2,Step3]


我期望的是:


[第一个服务呼叫]

[下一个服务呼叫]

[步骤列表]:[Step1,Step2,Step3]

收听步骤1

收听步骤2

正在聆听Step3


因此,不会添加事件处理程序(取决于之前步骤中生成的HTML)某些原因和 console.log 消息不显示。



当我调用 / em>从REPL我看到的输出,即:


repl =>(set-button-event-handlers!

(#object [Object [object Object]] #object [Object [object Object]] #object [Object [object Object]])


而控制台输出为:


到Step1

聆听Step2

聆听Step3


为什么可以 set-button-event-handlers!从REPL调用,但不在 update-transition-buttons c $ c> update-buttons ?

解决方案

看起来像这样的问题:

 (map listen-to-transition-button!名称)

set-button-event-handlers!



它创建一个延迟seq,元素将不会实现,直到他们在代码中的某处(这从不发生),但是当你调用它在repl ,它被完全实现以显示输出中的所有元素。尝试将此行更改为:

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


I have code that updates the DOM. new-recipe! calls an API to get a new recipe string. update-recipe-state next updates this state in the screen. Finally we have a call to 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:

(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). Again there is a timeout, and then I want to add the event handlers to the buttons. This is where it goes wrong.

The routine to create event listeners (which also contain a console.log) look as follows:

(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. The output I get in the Firefox console is:

[FIRST SERVICE CALLED]
[NEXT SERVICE CALLED]
[DISPLAY LIST OF STEPS]: ["Step1", "Step2", "Step3"]

What I expect is:

[FIRST SERVICE CALLED]
[NEXT SERVICE CALLED]
[DISPLAY LIST OF STEPS]: ["Step1", "Step2", "Step3"]
Listening to Step1
Listening to Step2
Listening to 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.

When I call the same code from the REPL I do see the output, i.e.:

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

And the console output is:

Listening to Step1
Listening to Step2
Listening to Step3

Why can set-button-event-handlers! be called from the REPL, but not in the update-transition-buttons method after update-buttons?

解决方案

looks like the problem is here:

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

in 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. Try changing this line to:

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

这篇关于代码不是从go块调用,但它的工作原理是REPL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆