AniUI Academy

Write debounce from scratch

mediumFunctions & ClosuresHigh freq+250 XPPractice Available

Debouncing controls how often a function can execute over time. When a JavaScript function is debounced with a wait time of wait milliseconds, it runs only after wait milliseconds have elapsed since the debounced function was last called.

You have probably encountered debouncing in daily life before, such as when entering an elevator. Only after some time passes without pressing the 'Door open' button (the debounced function not being called) will the elevator door actually close (the callback function is executed).

Implement debounce(fn, wait) so that fn is called only after wait milliseconds have passed since the most recent call. The returned function should not invoke fn immediately. When the delayed call finally runs, it should use the latest arguments and preserve the this value from the most recent call.

Arguments

fnFunction
The callback to debounce.
waitnumber
The number of milliseconds to wait after the latest call.

Returns

Function — A debounced version of fn. Also exposes .cancel(), which drops any pending call.

Examples

let i = 0;
function increment() { i++; }
const debouncedIncrement = debounce(increment, 100);

// t = 0: nothing happens yet
debouncedIncrement();

// t = 50: still waiting
// t = 100: increment runs once, i === 1

A single call fires once, 100ms after the invocation.

let value = null;
const update = (v) => { value = v; };
const debounced = debounce(update, 100);

debounced("j");
debounced("ja");
debounced("jav");
// 100ms later: value === "jav"

Rapid-fire calls collapse to one — using the most recent arguments.

const d = debounce(() => console.log("fired"), 100);
d();
d.cancel(); // nothing prints — the pending call was dropped

.cancel() discards any scheduled invocation.

What it has to do

  • Reset the timer every time the debounced function is called again.
  • Call fn with the arguments from the most recent call.
  • Preserve this when the debounced function is used as a method.
  • Expose a .cancel() that stops a pending call.

Notes

  • Debounce is _trailing_ by default — the callback fires at the end of the quiet period, not at the start. A leading variant is a separate problem.
  • Avoid using arrow functions for the returned function if you want to preserve this. Arrow functions capture this from the surrounding scope.
Asked atMetaGoogleAmazonMicrosoftUberStripe

Stuck? The javascript course covers everything this challenge needs.

Try it yourself
Loading playground...
4 tests · +250 XP

Discussion

Sign in to post
Sign in to join the conversation.Sign in

No comments yet. Be the first to say something.