Function debounce

Returns a debounce function which acts to filter calls to a given function fn.

Eg, Let's create a debounced wrapped for a function:

const fn = () => console.log('Hello');
const debouncedFn = debounce(fn, 1000);

Now we can call debouncedFn() as often as we like, but it will only execute fn() after 1 second has elapsed since the last invocation. It essentially filters many calls to fewer calls. Each time debounceFn() is called, the timeout is reset, so potentially fn could never be called if the rate of debounceFn being called is faster than the provided timeout.

Remember that to benefit from debounce, you must call the debounced wrapper, not the original function.

// Create
const d = debounce(fn, 1000);

// Don't do this if we want to benefit from the debounce
fn();

// Use the debounced wrapper
d(); // Only calls fn after 1000s

A practical use for this is handling high-frequency streams of data, where we don't really care about processing every event, only last event after a period. Debouncing is commonly used on microcontrollers to prevent button presses being counted twice.

// Set up debounced handler
const moveDebounced = debounce((elapsedMs, evt) => {
// Handle event
}, 500);

// Wire up event
el.addEventListener(`pointermove`, moveDebounced);

Arguments can be passed to the debounced function:

const fn = (x) => console.log(x);
const d = debounce(fn, 1000);
d(10);

If the provided function is asynchronous, it's possible to await the debounced version as well. If the invocation was filtered, it returns instantly.

const d = debounce(fn, 1000);
await d();