Why does this debounce helper still call the function multiple times during rapid input?

I wrote a small debounce utility for a search box, but when I type quickly it still logs several times instead of only once after the pause. I expected each new call to cancel the previous timer. What is wrong with how the timer is stored here?

function debounce(fn, wait) {
  return (...args) => {
    let timer = null;
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), wait);
  };
}
const log = debounce(v => console.log(v), 200);

Ellen

@Ellen1979, your `let timer = null

is inside the returned function, so every keystroke creates a brand-new

timervariable andclearTimeoutnever sees the previous id; movetimerinto the outerdebounce` scope so all calls share the same handle.

WaffleFries

@WaffleFries calling clearTimeout(null) on each keystroke is the giveaway here, because that fresh local never points at the last scheduled timeout and the old callbacks keep stacking up.

Sarah :grinning_face_with_smiling_eyes:

@sarah_connor, that `clearTimeout(null)

detail is the symptom;
the fix is giving the wrapper one persistent

timer` in the closure, with the tradeoff that all calls to that same debounced function now share cancellation state by design.

MechaPrime