【问题标题】:Block until a DOM event occurs with core.async阻塞直到使用 core.async 发生 DOM 事件
【发布时间】:2017-06-26 13:14:40
【问题描述】:

我有一个 Clojurescript 项目,我需要在其中阻止整个线程执行,直到发生 DOM 事件。

在这种情况下,事件是DOMContentLoaded,当初始 HTML 文档完全加载和解析时触发。但它可以扩展到任何 DOM(或非 DOM)事件。

由于我是 Clojurescript 和异步的新手,我不知道如何解决这个问题。我的第一个猜测是使用 core.async 库。经过一些文档抓取后,我有了这个功能:

(defn wait-dom-loading
  []
  (let [c (async/chan)]
 {1} (.addEventListener js/document "DOMContentLoaded" (fn [] (async/go (async/>! c true))))
 {2} (async/go (async/<! c))))

我理解它的方式是 {2} chan c 获取 并停在 {1} 中的侦听器评估函数并 puts chan c 中的一个值。

由于我几乎不了解如何对异步代码进行单元测试(除了将其放入 (async done) 表达式并在完成时调用 done),我无法验证我所做的是否正确。我试过这个 sn-p:

(do
  (wait-dom-loading)
  (-> (dommy/sel1 :p)
      (dommy/set-text! "Loaded !")))

在 html 页面中使用 p 块,并注意到控制台抱怨 js 代码试图操作尚不存在的 DOM 对象。这证实了我所做的并没有按计划进行。

  1. 此示例中似乎有什么问题?
  2. 这是矫枉过正吗?我可以用更小的解决方案或什至 gasp 内置功能来解决这个问题吗?
  3. 将我的脚本放在我的 html 页面底部是不是很糟糕的做法?

由于这是我关于堆栈溢出的第一个问题,我希望它写得足够​​好。

【问题讨论】:

    标签: clojurescript core.async


    【解决方案1】:

    我会这样做:

    (ns domevent.core
        (:require [cljs.core.async :as async :refer [chan]])
        (:require-macros [cljs.core.async.macros :refer [go]]))
    
    (enable-console-print!)    
    (def ch (chan))
    
    (go
        (pr "i am waiting")
        (pr (<! ch))
        (dommy/set-text! (dommy/sel1 :p) "Loaded !"))
    
    (.addEventListener js/document "DOMContentLoaded" (fn [] (go (>! ch "hello"))))
    

    或者更简单地说:

    (let [ch (chan)]
        (go
            (pr "i am waiting")
            (<! ch)
            (dommy/set-text! (dommy/sel1 :p) "Loaded !"))
    
        (.addEventListener js/document "DOMContentLoaded" #(close! ch)))
    )
    

    这里的重点是 ch,它是由 reader 和 writer 共享的。当(&lt;! ch) 发生时,ch 中还没有任何内容,因此该线程被停放(即停止并等待任何内容出现在 ch 中)。同时,DOMContentLoaded 发生,处理程序写入通道。然后前一个线程继续。

    【讨论】:

    • 谢谢。我认为我们应该更明确地编辑您的答案,我花了一些时间才意识到我想要的就在其中。也是 .addEventListener 似乎是要评估的第一个表达式。 Dommy 在这里实际上无关紧要,我想我会从我的问题中删除它。由于我最近的帐户,我没有很高,我无法使编辑生效,但也许有人可以查看/接受它?
    • 没关系,忽略我对 .addEventListener 位置的评论。 :)
    猜你喜欢
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 1970-01-01
    • 2021-08-15
    相关资源
    最近更新 更多