Last active
December 27, 2015 15:19
-
-
Save pangloss/7346742 to your computer and use it in GitHub Desktop.
delay-chan
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns async | |
(:require cljs.core.match | |
[cljs.core.async.impl.protocols :as impl] | |
[cljs.core.async.impl.channels :as channels])) | |
(defn delay-chan* | |
"chan-thunk is something that when deref'd returns a channel. The | |
first thing that that channel emits will be saved and always returned | |
by the channel this produces." | |
[chan-thunk] | |
(let [state (atom ::start) | |
c (reify | |
impl/Channel | |
(close! [_] (reset! state nil)) | |
impl/ReadPort | |
(take! [_ fn1] | |
(let [data @state] | |
(cond | |
(= ::start data) | |
(let [ret | |
(impl/take! @chan-thunk | |
(reify | |
impl/Handler | |
(active? [_] (impl/active? fn1)) | |
(lock-id [_] (impl/lock-id fn1)) | |
(commit [_] | |
(let [f1 (impl/commit fn1)] | |
(fn [result] | |
(reset! state result) | |
(f1 result))))))] | |
(if (and ret (not (nil? @ret))) | |
(channels/box @ret) | |
ret)) | |
data (channels/box data) | |
:else nil))))] | |
c)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns macros) | |
(defmacro delay-chan [& forms] | |
`(async/delay-chan* (delay ~@forms))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns usage | |
(:require async | |
[cljs.core.async :refer [<! timeout take!]]) | |
(:require-macros [macros :refer [delay-chan]] | |
[cljs.core.async.macros :refer [go]])) | |
(let [ch (delay-chan (go (.log js/console "starting work") | |
(<! (timeout 1000)) | |
"Done!"))] | |
(.log js/console "Decide whether to do work") | |
(take! ch #(.log js/console "result: " %)) | |
(take! ch #(.log js/console "result 2: " %))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment