Last active
April 4, 2020 16:05
-
-
Save jaidetree/1d84d332a8afc9dcc1dbb48309811407 to your computer and use it in GitHub Desktop.
A WIP library of promise macros for ClojureScript
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 cljs.promise | |
(:refer-clojure :exclude [resolve])) | |
(defmacro promise | |
" | |
Example: | |
(promise (resolve 5)) | |
(promise (reject (js/Error. \"oops\"))) | |
" | |
[body] | |
`(js/Promise. (fn [~'resolve ~'reject] ~body))) | |
(defmacro promise-> | |
" | |
Example: | |
(promise-> (.resolve js/Promise {}) $ | |
(assoc $ :a 1) | |
(assoc $ :b 2) | |
(println)) | |
;; => {:a 1 :b 2} | |
;; => #object[Promise [object Promise]] | |
" | |
[expr name & forms] | |
`(let [~name ~expr] | |
(-> ~name | |
~@(map (fn [form] | |
`(.then (fn [~name] | |
~form))) forms)))) | |
(defmacro then | |
" | |
Example: | |
(-> (promise (resolve {})) | |
(then [resources] (-> (.launch \"puppeteer\") | |
(then [browser] | |
(assoc resources :browser browser))))) | |
" | |
([a-promise body] | |
`(.then | |
~a-promise | |
(fn ~'success | |
[] | |
~body))) | |
([a-promise bindings & body] | |
`(.then | |
~a-promise | |
(fn ~'success | |
~bindings | |
~@body)))) | |
(defmacro catch | |
" | |
Example: | |
(-> (promise (reject \"err\")) | |
(catch [msg] (println msg))) | |
" | |
([a-promise body] | |
`(.catch ~a-promise | |
(fn catch | |
[] | |
~body))) | |
([a-promise bindings body] | |
`(.catch ~a-promise | |
(fn catch | |
~bindings | |
~body)))) | |
(defmacro resolve | |
" | |
Example: | |
(resolve {}) | |
" | |
[x] | |
`(.resolve js/Promise ~x)) | |
(defmacro reject | |
" | |
Example: | |
(reject {}) | |
" | |
[x] | |
`(.reject js/Promise ~x)) |
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 cljs.async | |
(:refer-clojure :exclude [delay]) | |
(:require-macros | |
[cljs.promise :refer [promise->] :as p])) | |
(defn resources | |
" | |
Example: | |
(resources | |
:browser (fn [] | |
(.launch puppeteer)) | |
:page (fn [{:keys [browser]}] | |
(promise-> (.pages browser) pages | |
(nth pages 0))) | |
nil (fn [{:keys [page]}] | |
(.goto page \"https://google.com\"))) | |
" | |
[init & resources] | |
(reduce | |
(fn [res [name setup]] | |
(println name res) | |
(if name | |
(promise-> res resources | |
(promise-> (setup resources) resource | |
(assoc resources name resource))) | |
(promise-> res resources | |
(setup resources) | |
res))) | |
(p/resolve init) | |
(partition 2 resources))) | |
(defn tasks | |
" | |
Example: | |
(tasks {} | |
(fn [{:keys [page]}] | |
(.click page \"play\"))) | |
" | |
[res & tasks] | |
(let [res-promise (p/resolve res)] | |
(reduce | |
(fn [chain task] | |
(promise-> res-promise res-map | |
(task res-map) | |
res-promise)) | |
tasks))) | |
(defn timeout | |
" | |
Example: | |
(-> (timeout (* 7 60 1000)) | |
(p/then (println \"pizza is ready\") )) | |
" | |
[ms] | |
(p/promise | |
(js/setTimeout #(resolve (.now js/Date)) ms))) | |
(defn delay | |
" | |
Example: | |
(-> (delay (* 7 60 1000) \"pizza is ready\") | |
(p/then [msg] (println msg) )) | |
" | |
[ms x] | |
(-> (timeout ms) | |
(p/then [_] x))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment