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 
@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