In this article, we see debouncing and throttling with the help of code examples and use cases.
Debouncing
A common use case of debouncing is the search bar on a website. When we type something in the search bar, it makes an API call to fetch data from the server related to entry in the search bar.
Let us understand with the help of examples.
Let us implement API call without debouncing.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<input type="text" onkeydown="APIcall()"/>
<script src="concepts.js"></script>
</body>
</html>
concepts.js
var countervariable=1;
function APIcall(){
countervariable=countervariable+1;
console.log("Aaku",countervariable)
}
output:
In the above code sample, we see that APIcall() function is called every time the user searches something in the search bar. Imagine having millions of users and millions of searches. Then we will need to make billions of call to API which is not possible. This is where debouncing comes into sight.
In the debouncing technique, no matter how many times the user fires the event, the attached function will be executed only after the specified time once the user stops firing the event.
For example, if one APIcall() is called at the starting of the event next APIcall() will be called after 300ms only.
Now let us see code for debouncing:
// Debouncing in Javascript
let counter = 0;
const getData = () => {
// calls an API and gets Data
console.log("Fetching Data ..", counter++);
}
const debounce = function (fn, d) {
let timer;
return function () {
/*
1) Assign `this` to a variable named `context` so that the
`func` argument passed to our `debounce` method can be
called in the proper context.
2) Assign all *arguments passed in the `func` argument of our
`debounce` method to a variable named `args`.
JavaScript natively makes all arguments passed to a function
accessible inside of the function in an array-like variable
named `arguments`. Assigning `arguments` to `args` combines
all arguments passed in the `func` argument of our `debounce`
the method in a single variable.
*/
let context = this,//1
args = arguments;//2
/*
When setTimeout is called, it returns a numeric ID. This unique ID
can be used in conjunction with JavaScript's `clearTimeout` method
to prevent the code passed in the first argument of the `setTimout`
function from being called. Note, this prevention will only occur
if `clearTimeout` is called before the specified number of
milliseconds passed in the second argument of setTimeout have been
met.
*/
clearTimeout(timer);
timer = setTimeout(() => {
getData.apply(context, args);
}, d);
}
}
const APIcall = debounce(getData, 300);
Output:
Throttling
Throttling is a technique in which, no matter how many times the user fires the event, the attached function will be executed only once in a given time interval.
The code of throttling :
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<button onclick="handleClick()">Click me</button>
<script src="concepts.js"></script>
</body>
</html>
concept.js
function throttle(func, delay) {
let isRunning;
return function() {
if(!isRunning) {
isRunning = true;
func()
setTimeout(function() {
isRunning = false;
}, delay);
}
}
}
function myFunc() {
console.log('Called');
}
let throttleFunc = throttle(myFunc, 300);
function handleClick() {
throttleFunc();
}
Output:
handleClick() function is called when we click the button for the first time, it then sets isRunning as true.isRunning is turned false only when setTimeout() has worked for 300ms.
Both throttling and debouncing are used to rate limit/optimize the function call.No one has an advantage over others. It completely on a use case to either use debouncing or throttling.
That's it for this article