Skip to content

Instantly share code, notes, and snippets.

@chr15m
Last active March 24, 2017 16:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chr15m/9f7530ffe22e1049eeaf to your computer and use it in GitHub Desktop.
Save chr15m/9f7530ffe22e1049eeaf to your computer and use it in GitHub Desktop.
ClojureScript setTimeout that fires reliably in a background tab.
; 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))
@chr15m
Copy link
Author

chr15m commented Dec 15, 2015

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment