Debounce With Trailing Edge Invocation
A debounce utility that collapses rapid calls into one trailing invocation with flush and cancel support for deterministic tests.
Code
export function debounce(fn, waitMs, scheduler = setTimeout) {
if (typeof fn !== "function") throw new TypeError("fn must be a function");
if (!Number.isFinite(waitMs) || waitMs <= 0) throw new RangeError("waitMs must be a positive number");
let timer = null;
let lastArgs = null;
const wrapped = (...args) => {
lastArgs = args;
if (timer !== null) clearTimeout(timer);
timer = scheduler(() => {
timer = null;
const a = lastArgs;
lastArgs = null;
fn(...a);
}, waitMs);
};
wrapped.flush = () => {
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
if (lastArgs !== null) {
const a = lastArgs;
lastArgs = null;
fn(...a);
}
};
wrapped.cancel = () => {
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
lastArgs = null;
};
return wrapped;
}Report a problem with this exampleOpens a pre-filled issue on GitHub.