Glossary / Debouncing

Debouncing

Debouncing delays invoking a function until a burst of calls has stopped for a specified interval. Each new call resets the timer, so only the final call in a rapid sequence runs. It is useful for search-as-you-type, resize handling, and autosave when intermediate events are not valuable.

Trailing, leading, and cancellation

A trailing debounce invokes after the quiet period; a leading debounce invokes immediately and may suppress later calls until the period ends. Some implementations support both, maxWait, cancellation, and flushing. Define which behavior is intended—libraries vary.

function debounce(fn, delay) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

This minimal version loses this, does not expose cancel/flush, and can retain arguments until execution; production code may need stronger lifecycle semantics. Debouncing does not cancel an async operation already started. For typeahead, combine it with AbortController or request-version checks so stale responses cannot overwrite newer results. Do not debounce accessibility-critical feedback or actions that must happen immediately without conveying the delay.

Interview questions

  1. What does debounce do? Runs after calls stop for a quiet interval, commonly only the trailing call.
  2. Debounce versus throttle? Debounce waits for inactivity; throttle caps invocation frequency during continuous activity.
  3. Does debounce cancel an in-flight fetch? No.
  4. What options matter? Leading/trailing, maxWait, cancel, flush, receiver, and lifecycle cleanup.

References