Docs

JS Machine Coding Questions — Implementations You Must Know

Debounce


  • Wait until calls stop for wait ms, then run once — classic for search-as-you-type and resize.
  • Key insight: Each new call clears the pending setTimeout and schedules a fresh one.
  • Trailing (default) fires after the burst; leading fires on the first call in a burst.
  • Gotcha: Always expose .cancel() so callers can clear the timer on unmount.
  • Gotcha: production libraries (Lodash) also support maxWait.
1// Trailing only 2function debounce(fn, wait) { 3 let timeoutId; 4 function debounced(...args) { 5 clearTimeout(timeoutId); 6 timeoutId = setTimeout(() => fn.apply(this, args), wait); 7 } 8 debounced.cancel = () => clearTimeout(timeoutId); 9 return debounced; 10} 11 12// Leading + trailing 13function debounce(fn, wait, { leading = false, trailing = true } = {}) { 14 let timeoutId; 15 return function (...args) { 16 const pending = timeoutId != null; 17 clearTimeout(timeoutId); 18 if (leading && !pending) fn.apply(this, args); 19 timeoutId = setTimeout(() => { 20 timeoutId = null; 21 if (trailing && (pending || !leading)) fn.apply(this, args); 22 }, wait); 23 }; 24}