diff --git a/src/computersandblues/lodestone/app.cljs b/src/computersandblues/lodestone/app.cljs index 565989d..945705c 100644 --- a/src/computersandblues/lodestone/app.cljs +++ b/src/computersandblues/lodestone/app.cljs @@ -267,18 +267,21 @@ ;;; views -(defn debounce [ms f] +(defn debounce + "Wraps `f` so it's called at most once every `ms` milliseconds. Will schedule + the last call to `f` so that it's called after the delay has passed, and will + always prefer to call the most recent call to `f` as close to the delay + as possible." + [ms f] (let [prev (volatile! (js/Date.now)) - trail (volatile! (js/setTimeout (fn dummy []) ms))] + scheduled (volatile! (js/setTimeout (fn dummy []) ms))] (fn debounced-fn [& args] (let [now (js/Date.now)] - (if (> (- now @prev) ms) - (do (vreset! prev now) - (apply f args)) - (do (js/clearTimeout @trail) - (vreset! trail (js/setTimeout (fn [] - (vreset! prev (js/Date.now)) - (apply f args)))))))))) + (js/clearTimeout @scheduled) + (vreset! scheduled (js/setTimeout (fn [] + (vreset! prev (js/Date.now)) + (apply f args)) + (max 0 (- ms (- now @prev))))))))) (defn search [] [:input {:placeholder "Start typing to search…"