Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
core.async debounce
(defn debounce [in ms]
(let [out (chan)]
(go-loop [last-val nil]
(let [val (if (nil? last-val) (<! in) last-val)
timer (timeout ms)
[new-val ch] (alts! [in timer])]
(condp = ch
timer (do (>! out val) (recur nil))
in (recur new-val))))
out))
@felixflores

Thanks for this 😃

@aiba
aiba commented Apr 18, 2016

Nice!

@wilkerlucio

nice, just one comment, this implementation has one issue, that is when you close the in channel it gets into an infinite loop by recurring with new-val as nil all the time, the fix is simple, just check the value when receiving from in:

(defn debounce [in ms]
  (let [out (chan)]
    (go-loop [last-val nil]
      (let [val (if (nil? last-val) (<! in) last-val)
            timer (timeout ms)
            [new-val ch] (alts! [in timer])]
        (condp = ch
          timer (do (>! out val) (recur nil))
          in (if new-val (recur new-val)))))
    out))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment