The function to debounce.
Optionaldelay: number = 100The number of milliseconds to delay.
Optionaloptions: { leading?: boolean; maxWait?: number; trailing?: boolean } = {}Optional settings.
Optionalleading?: booleanWhether to invoke on the leading edge.
OptionalmaxWait?: numberMaximum time to wait before forcing a call.
Optionaltrailing?: booleanWhether to invoke on the trailing edge.
A debounced function with a .cancel() method to clear pending calls.
const log = withDebounce(console.log, 300, { leading: true, trailing: true });
log('hello'); // logs immediately
log('world'); // ignored
setTimeout(() => log('again'), 400); // logs 'again' after delay
const fn = withDebounce(fetchData, 200, { maxWait: 1000 });
window.addEventListener('resize', fn);
// To cancel:
fn.cancel();
export const withDebounce = (
callback: (...args: unknown[]) => void,
delay: number = 100,
options: {
leading?: boolean;
trailing?: boolean;
maxWait?: number;
} = {}
): DebouncedFunction => {
let timeout: ReturnType<typeof setTimeout> | null = null;
let maxWaitTimeout: ReturnType<typeof setTimeout> | null = null;
let lastArgs: unknown[] | null = null;
let lastThis: any = null;
let calledLeading = false;
const { leading = false, trailing = true, maxWait } = options;
const clearTimers = () => {
if (timeout) clearTimeout(timeout);
if (maxWaitTimeout) clearTimeout(maxWaitTimeout);
timeout = null;
maxWaitTimeout = null;
};
const invokeCallback = () => {
if (trailing && lastArgs) {
callback.apply(lastThis, lastArgs);
}
clearTimers();
lastArgs = null;
lastThis = null;
calledLeading = false;
};
const debounced = function (this: any, ...args: unknown[]) {
lastArgs = args;
lastThis = this;
const shouldCallLeading = leading && !calledLeading;
if (shouldCallLeading) {
callback.apply(lastThis, lastArgs);
calledLeading = true;
lastArgs = null;
lastThis = null;
}
if (timeout) clearTimeout(timeout);
timeout = setTimeout(invokeCallback, delay);
if (maxWait && !maxWaitTimeout) {
maxWaitTimeout = setTimeout(() => {
if (lastArgs) {
callback.apply(lastThis, lastArgs);
clearTimers();
lastArgs = null;
lastThis = null;
calledLeading = false;
}
}, maxWait);
}
} as DebouncedFunction;
debounced.cancel = () => {
clearTimers();
lastArgs = null;
lastThis = null;
calledLeading = false;
};
return debounced;
};
Creates a debounced version of the provided callback function. The debounced function delays the invocation of the callback until after a specified wait time has elapsed since the last time it was called.
Supports options for: