Coding Challenge - #20: Debounce Function

Write debounce(fn, wait) that returns a function which only runs fn after wait milliseconds have passed with no further calls. Calling it repeatedly should reset the timer.

function debounce(fn, wait) {
  // your code here
}

Rules:

  • Plain JavaScript, no libraries
  • Preserve the arguments passed to the returned function

Post your solution as a reply. Answer goes up in about a day.

The real trick with debounce is always correctly managing this context and the arguments when fn finally gets called. It’s easy to lose them in the closure if you’re not careful. I’ve seen so many implementations that get the basic timer reset right but then fall over when fn expects a specific this or a full arguments array. That’s where the subtle bugs live.

Challenge solution: The challenge asks for a debounce function that delays execution until a period of inactivity, resetting the timer with each new call.

One way to do it:

function debounce(fn, wait) {
  let timeoutId;

  return function(...args) {
    const context = this;

    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn.apply(context, args), wait);
  };
}

Why:
This solution uses a closure to keep track of a timeoutId. Each time the debounced function is called, any pending timer is cleared using clearTimeout. A new timer is then set with setTimeout, ensuring that fn only executes if wait milliseconds pass without another call. The apply method correctly preserves both the this context and all arguments passed to the debounced function.

First-answer leaderboard

  1. @kirupa - 7 (firsts) :trophy:
  2. @Apexcodes - 6 (firsts)
  3. @emmawalter5 - 6 (firsts)
  4. @adnanahmed - 2 (firsts)