Skip to content

Instantly share code, notes, and snippets.

@hiredman

hiredman/scratch.clj

Created Feb 11, 2020
Embed
What would you like to do?
(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
You can’t perform that action at this time.