2015-01-02 4 views
0

При загрузке веб-сайта мне часто приходится загружать код ПОСЛЕ того, как произошло другое структурное событие DOM. Поэтому я часто оказываю много функций, которые сначала проверяют, существует ли какой-то элемент в DOM, а затем выполняют свою задачу в том случае, если указанный элемент существует.машина core.async, которая работает до тех пор, пока fx не вернется.

(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 не находится в состоянии, в котором функция может преуспеть (возвращает истину); без необходимости проходить большую церемонию с точки зрения борьбы с повторной попыткой (просто вернемся к успеху).

Я ищу улучшения для loop-until-true, функция, которая регистрирует другую функцию, чтобы продолжать выполнение, пока эта функция не вернет значение true. Я не хочу блокировать выполнение кода, который может привести к ошибке fx, поэтому я использую блок core.async для кода IOC. Этот код, похоже, работает, но я ищу улучшения и критики.

ответ

1

<body onload="f()"> и разместите свой код, который будет прослушиваться при нажатии на (defn f [] …).