(require '[clojure.core.async.impl.protocols :as impl] | |
'[clojure.core.async.impl.dispatch :as dispatch] | |
'[clojure.core.async.impl.channels :as c] | |
'[clojure.core.async :as async]) | |
;;=> nil | |
(defn wait [watchable expected?] | |
(reify | |
impl/ReadPort | |
(take! [this handler] | |
(let [k (Object.) | |
handle! (fn [] | |
(.lock handler) | |
(let [good (and (impl/active? handler) | |
(impl/commit handler))] | |
(.unlock handler) | |
good))] | |
(add-watch watchable k (fn [k r os ns] | |
(if (impl/active? handler) | |
(when-let [good (and (expected? os ns) | |
(handle!))] | |
(remove-watch watchable k) | |
(dispatch/run #(good ns))) | |
(remove-watch watchable k)))) | |
(let [v @watchable] | |
(when-let [good (and (expected? v v) | |
(handle!))] | |
(remove-watch watchable k) | |
(c/box v))))))) | |
;;=> #'user/wait | |
(def x (atom :foo)) | |
;;=> #'user/x | |
(first (async/alts!! [(async/timeout 1000) (wait x (fn [old new] (= new :bar)))])) | |
;;=> nil | |
(reset! x :bar) | |
;;=> :bar | |
(first (async/alts!! [(async/timeout 1000) (wait x (fn [old new] (= new :bar)))])) | |
;;=> :bar | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment