Implementing Debounce

Debounce

Debounce is a function that shows up way more often than you'd think.

When you debounce a function, you schedule that function to be called at a later time, unless the debounced function is called before that point, if it is the function call is delayed again.

In practice, debouncing is useful if you want to call a function after the user as stopped interacting with it. Take autocomplete for example, you might want to start searching 100ms after the user stops typing, so every time he types you call the debounced function to further delay it's invokation.


Base Case

The starting off point for me when thinking about debounce is to have debounce just call setTimeout. This doesn't get us too far functionality wise, but it sets us up to think about the nuts and bolts of the problem.

startTime = Date.now();

function yolo() {
  console.log("yolo", Date.now() - startTime);
}

function debounce(func, time) {
  setTimeout(func, time);  
}

debounce(yolo, 25);
Deficiencies:
  • debounce can not be called multiple times
  • calling the debounced function does not delay it's invocation

A closer approximation

When we update debounce we make sure that it returns a function that will delay the invocation. We do this by having the returned function reset a timeout. We also add a later function, which will does a check to see if the function has been called already. If so, it stops and doesn't do anything else.

// https://coderpad.io/WFQNQMW4


startTime = Date.now();

function yolo() {
  console.log("yolo", Date.now() - startTime);
}


function debounce(func, time) {
  var timeout;
  var ran = false;

  // called when the time is up
  function later() {
    if (!ran) func();
    ran = true;
  }

  // resets the timeout
  return function() {
    clearTimeout(timeout);
    timeout = setTimeout(later, time);
  }
}

dy = debounce(yolo, 25);   // schedule yolo for 25 ms, returns a debounced function
setTimeout(dy, 10);        // delays the invocation
setTimeout(dy, 15);        // delays the invocation again
setTimeout(dy, 50);        // does nothing because the function has been called already

17 Mar 2015