DEV Community

loading...

Debounce in JavaScript

EidorianAvi
My name is Adrian; currently a recent graduate of the Flatiron Software Engineering program. Broadening my knowledge base through posting and reading alike.
・3 min read

Something I came across this week while in an algorithm group was something called a debounce. The purpose of the debounce was really quite practical and I foresee myself using it in personal projects and professional settings alike. Today I'd like to demonstrate one case where it'd be ideal to implement as well as break down the base logic of the code. Let's get started.

What does it do?

It stops functions from firing again within a certain amount of time. Now why's that useful? Well what if it's an expensive task firing off or a time consuming one? What if a user makes a get request but constantly clicks the request making it over and over again. That can lead to poor performance and an insane amount of requests hitting the server. Here if you made it so the user can only request again after a certain amount of time it doesn't matter how many times the user clicks they're still limited to the same amount of requests based on time. Imagine somebody doing the same for a purchase and multiple purchases hit the server at the same time. That's why learning how to debounce in coding is important to protect both your user experience and what's going on server side as well.

How does it work

So to implement the debounce practice into your code you have to build it yourself it's not built into JavaScript. First things first let's just create a simple button like so.

<button id="debounceButton">Debounce Button</button>
Enter fullscreen mode Exit fullscreen mode

Okay so now that we have something to run a function on lets create the debounce function. The debounce function will take in two arguments right? The first being the function you need the delay on, and the second the amount of time to delay.

const debounce = ( fn, delay) => {

}
Enter fullscreen mode Exit fullscreen mode

From there we will declare a variable but not define it inside the function

   let timeout;
Enter fullscreen mode Exit fullscreen mode

Now we return a function inside our function. What does that make this? Correct, a higher order function.

const debounce = ( fn, delay) => {
   let timeout;

   return function(...args){

   }

}
Enter fullscreen mode Exit fullscreen mode

So here is where the magic happens. The first thing the function will do is check if the timeout is defined. If a timeout IS already defined it will reset it and then define it again. If it has never been defined then it goes on with its business and defines it for the first time.

return function(...args){

   if(timeout){
      clearTimeout(timeout);
   }

   timeout = setTimeout(() => {
       fn(...args);
   }, delay )
}
Enter fullscreen mode Exit fullscreen mode

See what happened there? The timeout variable is assigned to a setTimeout function that executes whatever function you passed in at a delay with the amount of time that was input. So effectively anytime you click it, it takes a set amount of time until the function is ran. If you click on it again and again within that delay it is resetting the timeout variable over and over again the function not being capable of running until that delay is up. So one more time in its full scale:

const debounce = ( fn, delay) => {
    let timeout;

    return function(...args){

        if(timeout){
            clearTimeout(timeout);
        }

        timeout = setTimeout(() => {
                fn(...args);
            }, delay);
    };
}
Enter fullscreen mode Exit fullscreen mode

Now let's see how it might look in action in conjunction with the button we created.

First I'm going to create a super simple function to pass into the debounce function.

const success = () => {
    console.log("success");
}
Enter fullscreen mode Exit fullscreen mode

Now I'm going to grab that button add an event listener to it and pass in our new success function.

document.querySelector('#debounceButton').addEventListener('click', debounce( success, 3000));
Enter fullscreen mode Exit fullscreen mode

So on click it will run our debounce where we pass in
the success function and a delay. Now we can click the button and it will log "success" to our console but not before 3 seconds have passed. If within that three second timeframe I click the button again it will reset the timeout and I will have to wait another 3 seconds to see that ever hit the console. I can not spam the click button and see "success" over and over and over again. I have to wait 3 seconds between each click for it to successfully perform. The desired delay is achieved and the debounce has occurred. That's it from me today thanks for checking this out I hope you learned something and as always happy coding.

Discussion (0)