Last active
March 24, 2017 16:09
-
-
Save chr15m/9f7530ffe22e1049eeaf to your computer and use it in GitHub Desktop.
ClojureScript setTimeout that fires reliably in a background tab.
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
; uses a web worker background thread | |
(let [metronome-worker-js "self.onmessage=function(e){setTimeout(function(){postMessage(e.data);},e.data.interval);};console.log('Metronome worker loaded.');" | |
worker-blob (js/Blob. (clj->js [metronome-worker-js]) {:type "application/javascript"}) | |
worker (js/Worker. (.createObjectURL js/URL worker-blob)) | |
call-id (atom 0)] | |
(defn make-worker-listener [id callback] | |
(fn [e] | |
(when (= e.data.id id) | |
(callback) | |
true))) | |
(defn set-timeout [callback interval] | |
(let [id (swap! call-id inc) | |
listener-fn (make-worker-listener id callback)] | |
(.addEventListener worker | |
"message" | |
(fn [e] | |
(when (listener-fn e) (.removeEventListener worker "message" listener-fn))) | |
false) | |
(.postMessage worker (clj->js {:id id :interval interval})))) | |
; this emulates async's timeout but in background worker thread | |
(defn timeout-worker [interval] | |
(let [c (chan)] | |
(set-timeout (fn [] (close! c)) interval) | |
c))) | |
(set-timeout (fn [] "Hello!") 1000) | |
; acts a bit like async's "timeout" but on a backgrounded tab | |
(go-loop [] | |
(<! (timeout-worker 500)) | |
(print "timeout!") | |
(recur)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
13:58:39.645 timeout 298 core.js:135:8
13:58:39.716 *** worker 958 core.js:135:8
13:58:39.820 timeout 309 core.js:135:8
13:58:40.017 timeout 324 core.js:135:8
13:58:40.027 *** worker 959 core.js:135:8
13:58:40.399 *** worker 960 core.js:135:8
13:58:40.679 timeout 299 core.js:135:8
13:58:40.705 *** worker 961 core.js:135:8
Above "timeout" is using setTimeout but "*** worker" is using (set-timeout)