Table of Contents

How to create a Debounce Function in Javascript?

About

A debounce is a function that:

For instance, in the context of:

debounce is said to come from the switch Contact bounce problem.

Usage

It's mostly used with event that triggers really often such as:

For example, in a search box that uses the change event, you don't want to search for every keystroke (ie to not search for every character of the search term)

Debounce function explained

This section will explain and comment on a debounce function to show how it works.

A debounce is a function that:

In Javascript, a call to the debounce function:

Function Signature

The signature of the debounce function has tree arguments:

function debounce(funcToDebounce, interval, leadingExecution) {

The timer Id

To execute after a certain amount of elpased time, the debounce function uses the setTimeOut function.

To keep track of the scheduled execution of the target function, we store the scheduler identifier (the returned value of the setTimeOut) in a timerId variable.

let timerId;

Every time that the debounce function is executed, this variable is not reset because we returns a function (it's called the closure functionality of javascript).

Returned function

Calling debounce returns a new anonymous function. Thanks to Javascript, this function is a closure and keeps track of its environment variables. The timerId will then persist and be available to this function.

return function() {

Scheduling condition

This condition checks if the function was already schedule.

It checks if timerId is a number (ie not null or undefined) and if this is the case it means that there is already a schedule running.

let wasFunctionScheduled = (typeof timerId === 'number');

Delete/Clear the previous schedule

The line below is the grand trick of the debounce function where:

clearTimeout will delete the previous schedule function if timerId is valid/set or do nothing otherwise

clearTimeout(timerId);

The function to schedule

funcToSchedule is a wrapper function that:

Steps:

let funcToDebounceThis= this, funcToDebounceArgs = arguments;
let funcToSchedule = function() {

      // Reset
      clearTimeout(timerId);
      timerId = null;

      // trailing execution happens at the end of the interval
      if (!leadingExecution) {
        // Call the original function with apply
        funcToDebounce.apply(funcToDebounceThis, funcToDebounceArgs);
      }
      
}

Schedule the function to run at interval

Schedule each time an execution of the function over the interval.

timerId = setTimeout(funcToSchedule, interval);

Leading Execution

If:

Execute the function..

if (!wasFunctionScheduled && leadingExecution) funcToDebounce.apply(funcToDebounceThis, funcToDebounceArgs);

End of the returned function

}

End of debounce function

}

Demo: Mouse location

function onMouseMove(e){
  console.log(new Date().toLocaleString()+": Position: x: "+e.x+ ", y:"+ e.y);
}
let debouncedMouseMove = debounce(onMouseMove, 500);
window.addEventListener('mousemove', debouncedMouseMove);

Library

A debounce function is also generally available in utility library such as:

Debounce vs Throttle vs Deferred

Documentation / Reference