Last active
September 29, 2021 09:12
-
-
Save reedho/af11377b1bc64908ff41c2336ea26561 to your computer and use it in GitHub Desktop.
@leonoel missionary in cljs
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
;; https://github.com/leonoel/missionary/tree/master/doc/tutorials | |
(ns my.web.app | |
(:require [missionary.core :as m])) | |
;; Basic how the `task` used in practice | |
(def slow-mo-hello-task | |
(m/sp (println "hello") | |
(m/? (m/sleep 1000)) | |
(println "world") | |
(m/? (m/sleep 1000)) | |
(println "!"))) | |
(comment | |
;; Run task from repl | |
(-> | |
(js/Promise. slow-mo-hello-task) | |
(.then #(println "done successfully with" %)) | |
(.catch #(println "done with error" %)))) | |
;; Create top level executor and helper fns | |
(defn execute! | |
[task s e] | |
;; s = successful continuation, a 1-arity fn of task result | |
;; e = error continuation, 1-arity fn of task result | |
(-> (js/Promise. task) | |
(.then s) | |
(.catch e))) | |
(defn log-success [r] | |
;; r = result | |
(js/console.log "SUCCESS" r)) | |
(defn log-error [r] | |
(js/console.error "ERROR" r)) | |
(defn promise->task | |
[p] | |
(fn [s e] | |
(-> p (.then s) (.catch e)))) | |
(defn fetch-json | |
[url] | |
(-> (js/fetch "https://randomuser.me/api/") (.then #(.json %)))) | |
(comment | |
;; Run fetch with `task` machinery | |
(execute! (promise->task | |
(-> (js/fetch "https://randomuser.me/api/") (.then #(.json %)))) | |
log-success | |
log-error) | |
;; sequentially | |
(execute! | |
(m/sp | |
(m/? (promise->task | |
(-> (js/fetch "https://randomuser.me/api/") (.then #(.json %))))) | |
(m/? (m/sleep 3000)) | |
(m/? (promise->task | |
(-> (js/fetch "https://randomuser.me/api/") (.then #(.json %)))))) | |
log-success | |
log-error) | |
;; paralel and join | |
(execute! | |
(m/sp | |
(m/join (comp into-array vector) | |
(promise->task (fetch-json "https://randomuser.me/api/")) | |
(promise->task (fetch-json "https://randomuser.me/api/"))) | |
(m/? (promise->task | |
(-> (js/fetch "https://randomuser.me/api/") (.then #(.json %)))))) | |
log-success | |
log-error) | |
) | |
(comment | |
;; Calling task manually | |
;; --- | |
(let [task (m/sp (println "computing heavily...") | |
(m/? (m/sleep 5000 100))) | |
;; task is 2-arity fn and called like below | |
canceller (task log-success log-error)] | |
:exit) | |
(let [t (m/sp (println "computing heavily...") | |
(m/? (m/sleep 5000 100))) | |
canceller (t log-success log-error)] | |
;; cancel after 2 seconds! | |
;; see that the error tell as that the sleep is cancelled. | |
(js/setTimeout (fn [] (canceller)) 2000)) | |
;; observe | |
;; --- | |
(defn subject | |
[event-fn] ;; call `event-fn` to provide value for the flow | |
(let [x (atom 0) | |
n (js/setInterval | |
;; In this case, we periodically call `event-fn` | |
;; every second | |
(fn [] (event-fn (swap! x inc))) 1000) | |
] | |
;; return 0-arity fn for cleanup | |
(fn [] | |
(println "CLEANUP") | |
(js/clearInterval n)))) | |
(let [t (m/reduce (constantly nil) | |
(m/ap | |
(println "GOT" (m/?< (m/observe subject))))) | |
c (t log-success log-error)] | |
(js/setTimeout (fn [] (c)) 10100)) | |
;; watch | |
;; --- | |
;; playing with atom | |
(def state (atom 0)) | |
(let [t (m/reduce (constantly nil) | |
(m/ap | |
(println "GOT" (m/?> (m/watch state))))) | |
c (t log-success log-error)] | |
;; cancel after 5 seconds | |
(js/setTimeout (fn [] (c)) 5000) | |
;; trigger/push value | |
(swap! state inc) | |
(swap! state (fn [x] (* (rand-int 100) x))) | |
) | |
;; dfv (data flow variable) a.k.a single-assignment | |
;; --- | |
(let [v (m/dfv) | |
c (v log-success log-error)] | |
;; assign | |
(v 10) | |
(v 20) ;; this will rejected | |
(c) | |
) | |
;; mailbox | |
;; --- | |
(let [mbx (m/mbx) | |
;;c (mbx log-success log-error) | |
] | |
;; post | |
(js/setTimeout | |
(fn [] | |
(println "POSTING") | |
(mbx 10)) | |
1000) | |
(js/setTimeout | |
(fn [] | |
(println "FETCHING") | |
(mbx log-success log-error)) | |
1100) | |
) | |
;; from the documentation | |
;; actor is mailbox associated with process consuming messages | |
(defn actor | |
([init] (actor init log-error)) | |
([init fail] | |
(let [self (m/mbx)] | |
((m/sp | |
(loop [b init] | |
(recur (b self (m/? self))))) | |
nil fail) | |
self))) | |
(def counter | |
(actor | |
((fn beh [n] | |
(fn [self cust] | |
(cust n) | |
(beh (inc n)))) | |
0))) | |
) | |
;; --- MAIN --- | |
(defn ^:dev/after-load start [] | |
(println "Reloaded at" (js/Date.))) | |
(defn ^:export init [] | |
(start)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment