Skip to content

Instantly share code, notes, and snippets.

@reedho
Last active September 29, 2021 09:12
Show Gist options
  • Save reedho/af11377b1bc64908ff41c2336ea26561 to your computer and use it in GitHub Desktop.
Save reedho/af11377b1bc64908ff41c2336ea26561 to your computer and use it in GitHub Desktop.
@leonoel missionary in cljs
;; 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