Skip to content

Instantly share code, notes, and snippets.

@loganlinn
Last active December 12, 2015 05:08
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loganlinn/4719107 to your computer and use it in GitHub Desktop.
Save loganlinn/4719107 to your computer and use it in GitHub Desktop.
(defn- debounce-future
"Returns future that invokes f once wait-until derefs to a timestamp in the past."
[f wait wait-until]
(future
(loop [wait wait]
(Thread/sleep wait)
(let [new-wait (- @wait-until (System/currentTimeMillis))]
(if (pos? new-wait)
(recur new-wait)
(f))))))
(defn debounce
"Takes a function with no args and returns a debounced version.
f does not get invoked until debounced version hasn't been called for `wait` ms.
The debounced function returns a future that completes when f is invoked."
[f wait]
(let [waiting-future (atom nil)
wait-until (atom 0)]
(fn []
(reset! wait-until (+ (System/currentTimeMillis) wait))
(locking waiting-future
(let [fut @waiting-future]
(if (or (not (future? fut)) (future-done? fut))
(reset! waiting-future (debounce-future f wait wait-until))
fut))))))
(let [f (debounce #(println "Invoked at:" (System/currentTimeMillis)) 50)
mk-thread #(Thread. (fn []
(dotimes [_ 10] (Thread/sleep (rand-int 20)) (f))
(println % "Exiting at:" (System/currentTimeMillis))))
thread-1 (mk-thread "thread-1")
thread-2 (mk-thread "thread-2")]
(.start thread-1)
(.start thread-2)
(.join thread-1)
(.join thread-2))
;; thread-1 Exiting at: 1360110519355
;; thread-2 Exiting at: 1360110519375
;; Invoked at: 1360110519426
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment