Why does this debounce helper call the function immediately on later keystrokes?

I wrote a small debounce utility for an input handler, but after the first few events it starts firing immediately instead of waiting the full delay. I expected each new call to reset the timer. What is wrong with the state handling here?

function debounce(fn, wait) {
  let timer = null;
  return (...args) => {
    if (timer) return;
    timer = setTimeout(() => {
      fn(...args);
      clearTimeout(timer);
    }, wait);
  };
}

How should this be fixed so rapid calls only invoke fn once after the last event?

MechaPrime

You built a throttle by accident because if (timer) return drops later keystrokes instead of rescheduling, and you also never set timer back to null.

Quelly :smiling_face_with_sunglasses: