Compile Ready
Module 11 · Advanced JavaScript

Debouncing

Advanced12m read22m practice34m total
DebounceTimersPerformanceMachine Coding

Introduction

Debouncing delays a function until calls have stopped for a specified amount of time. If a user triggers an event repeatedly, only the final call after the quiet period runs.

In interviews, debounce is the canonical timer machine-coding question. A strong answer handles trailing execution, optional leading execution, argument preservation, this, and cancellation.

Why This Matters

Debouncing protects expensive work from bursty input: search boxes, resize recalculation, autosave, validation, and analytics. It tests whether you can reason about asynchronous timers and state that survives across calls.

Theory

Mental model

Each call resets a timer. The wrapped function runs only if no new call arrives before the timer expires. That is why debounce is ideal for wait-until-the-user-pauses behavior.

Trailing vs leading

Trailing debounce runs after the quiet period with the latest arguments. Leading debounce runs immediately on the first call in a burst, then suppresses later calls until the wait window closes. Some utilities support both, but the implementation must avoid double-calling a single isolated invocation.

Debounce vs throttle

Debounce waits for silence. Throttle allows execution at a maximum rate. For a search input, debounce usually makes sense. For scroll progress, throttle usually makes sense.

Implementation state

A debounce wrapper stores a timer id, latest arguments, and latest receiver. On every call, it clears the old timer and schedules a new one.

Visual Diagrams

Debounce timeline
calls:  A ---- B ---- C ---------------- D
wait:        reset reset run C after quiet   run D
output:                 C                    D

Only the last call in each burst survives the quiet period.

Code Examples

Debounce with leading and trailing options

This implementation is framework-agnostic and works anywhere setTimeout exists.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1function debounce(fn, wait) {
2 var timer = null;
3 return function (value) {
4 clearTimeout(timer);
5 timer = setTimeout(function () {
6 fn(value);
7 }, wait);
8 };
9}
10
11var log = debounce(function (value) {
12 console.log(value);
13}, 20);
14
15log('A');
16setTimeout(function () { log('B'); }, 5);
17setTimeout(function () { log('C'); }, 10);
18setTimeout(function () { log('D'); }, 40);
19setTimeout(function () { console.log('done'); }, 80);

Coding Exercises

Build debounce with cancel and flush

Hard

Implement debounce(fn, wait, options) with trailing execution by default, optional leading, plus .cancel() and .flush() methods. Preserve the latest arguments and this value.

Interview Questions

1Explain debounce vs throttle with an example for each.

Debounce waits until calls stop, fitting search suggestions after typing pauses. Throttle runs at most once per interval, fitting scroll or resize progress updates during continuous activity.

Asked at:GoogleMetaUber

Follow-ups

  • How do leading and trailing debounce differ?
  • How would you add cancel support?
2Why must debounce store the latest arguments?

The call that finally runs should represent the most recent event in the burst. Without latest arguments and receiver, the delayed call can execute with stale data or the wrong this value.

Quiz

1. A trailing debounce is best described as:

Summary

  • Debounce waits for a quiet period before invoking the function.
  • Trailing debounce runs with the latest arguments after the burst.
  • Leading debounce runs at the start of a burst and suppresses later calls during the wait window.
  • A complete implementation preserves `this`, supports cancellation, and avoids stale arguments.

Cheat Sheet

Debounce: reset timer on every call.

Trailing: run after silence with latest args.

Leading: run immediately on first call in burst.

Use for: search input, autosave, validation, resize end.

State: timer id, latest args, latest receiver.