Машина core.async, которая зацикливается, пока fx не вернет true
При загрузке веб-сайта мне часто приходится загружать код ПОСЛЕ того, как произошло другое структурное событие 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); без необходимости проходить большую церемонию с точки зрения повторных попыток (просто верните true в случае успеха).
Я ищу улучшения для loop-until-true
, функция, которая регистрирует другую функцию для продолжения выполнения, пока эта функция не вернет true. Я не хочу на самом деле блокировать выполнение кода, который может вызвать fx
чтобы передать, поэтому я использую блок core.async для IOC кода. Кажется, этот код работает, но я ищу улучшения и критику.
1 ответ
<body onload="f()">
и поместите ваш код, который слушает, нажмите на (defn f [] …)
,