Debounce on the leading edge
Ordinary debounce is trailing: it waits for quiet, then acts. That is right for a search box and wrong for a button, where the user needs feedback now and protection from double-clicks after. Leading-edge debounce inverts it: act immediately, then swallow everything until things go quiet.
Implement leadingDebounce(fn, wait). It returns a wrapper. If no cooldown is currently pending, the wrapper invokes fn immediately, synchronously, with the same arguments and the same this, and returns fn's return value. Every call — whether or not it invoked fn — then starts a fresh cooldown of wait milliseconds, restarting any cooldown already running. While a cooldown is pending, calls do not invoke fn and return undefined. Only once a full wait has passed with no calls at all does the next call invoke fn again. There is no trailing call: the calls swallowed during a cooldown are never run later.
Arguments
fnFunction- The function to invoke on the leading edge.
waitnumber- Length of the cooldown, in milliseconds. The cooldown restarts on every call.
Returns
Function — A wrapper that fires on the first call of a burst, then swallows everything until things go quiet.
Examples
const submit = leadingDebounce(() => console.log("submit"), 500);
submit(); // logs "submit" immediately
submit(); // ignored — cooldown active
submit(); // ignored — cooldown restarted
// 500ms of silence later:
submit(); // logs "submit" againPerfect for a submit button where waiting for the trailing edge feels broken.
const double = leadingDebounce((n) => n * 2, 50);
double(5); // 10 — leading call returns fn's value
double(6); // undefined — suppressedWhat it has to do
- Invoke
fnsynchronously on the first call and return its result. - Suppress the rest of a burst and return
undefinedfor suppressed calls. - Never make a trailing call once the burst ends.
- Restart the cooldown on every call, so a steady stream of calls closer together than
waitonly ever fires once. - Invoke
fnagain on the first call after a fullwaitof silence.
Notes
- Let the timer handle double duty:
nullmeans "next call fires"; a non-null handle means "cooling down". Every call clears the old timer and sets a new one. - Opposite of trailing debounce: leading fires early then goes quiet; trailing waits for quiet then fires. Pick leading for buttons, trailing for search boxes.
Stuck? The javascript course covers everything this challenge needs.
- 1.fires immediately on the first call
- 2.swallows the rest of a burst and never fires a trailing call
- 3.fires again after the calls stop for wait ms
- 4.a steady stream closer together than wait fires only once
- 5.returns the result on the leading call and undefined when suppressed
These assertions run in your browser the moment you hit Run. Pass all of them to claim the XP.
Discussion
Sign in to postNo comments yet. Be the first to say something.