SnippetJavaScript

Debounce a function

The eight-line debounce that waits for typing to stop before firing — with the this-and-arguments handling naive versions drop.

Last updated

Snippetjavascript
function debounce(fn, delayMs) {
  let timer;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delayMs);
  };
}

// input.addEventListener("input", debounce(runSearch, 300));

How it works

Each call clears the previous timer and starts a new one, so the wrapped function runs only after the calls STOP for delayMs — the behaviour you want for search boxes and resize handlers, where only the final state matters.

The returned function is a regular function (not an arrow) and uses fn.apply(this, args) on purpose: it forwards both the caller's this and the event arguments, so it works as a method and as an event listener without wrapping.

Edge cases to know

  • Debounce delays the FIRST call too. If you need immediate-then-quiet behaviour (a button guard), you want a leading-edge variant or a throttle instead.
  • The pending timer survives component unmount — in React, clear it in the effect cleanup or the callback can fire against a dead component.
  • One debounced function holds one timer: create it once (not inside a render/loop) or every call gets a fresh timer and nothing is debounced.

Related in Snippets