core.async机器循环,直到fx返回true

时间:2015-01-02 02:27:28

标签: clojure clojurescript core.async

在加载网站时,我经常需要在发生其他一些DOM结构事件后加载代码。因此,我经常会遇到很多函数,这些函数首先检查DOM中是否存在某个元素,然后在所述元素存在的情况下执行它们。

(ns example.core
  (:require
   [cljs.core.async :as async]
   goog.async.AnimationDelay)
  (:require-macros
   [cljs.core.async.macros :refer [go go-loop]]))

(defn register-click-handler []
  (when js/window.document.body
    (goog.events.listen
      js/window.document.body
      goog.events.EventType.CLICK
      #(js/console.log "I was clicked!"))
    true))

(defn loop-until-true [fx]
  (let [c (async/chan)
        f (goog.async.AnimationDelay. #(async/put! c :loop))]
    (async/put! c :initial-loop)
    (go-loop []
      (async/<! c)
      (when-not (true? (fx))
        (.start f)
        (recur)))))

(loop-until-true register-click-handler)

我想我喜欢这种模式,因为它允许我编写fx一直尝试,直到DOM处于函数可以成功的状态(返回true);在处理重试方面无需经历大量仪式(只需在成功时返回)。

我正在寻找对loop-until-true的改进,fx是一个函数,它注册另一个函数以继续执行,直到该函数返回true。我不想实际阻止可能导致{{1}}传递的代码的执行,因此我使用core.async块来代码IOC。这段代码似乎有用,但我正在寻找改进和批评。

1 个答案:

答案 0 :(得分:1)

<body onload="f()">并将您点击的代码放入(defn f [] …)