throttleTime-vs-debounceTime-in-RxJS

View on GitHub

throttleTime vs debounceTime in RxJS

We all know that the Reactive Extensions for JavaScript (RxJS) is a library for composing asynchronous and event-based programs. RxJS comes with wide range of operators and in this blog we will discuss about throttleTime and debounceTime operators.

Before I move to throttleTime, lets understand what throttling means. So in simple terms throttling means to control the rate at which a process is conducted. So if you have situation when you want to start a process, then wait for x time and then resume and repeat the process, you would need to throttle that process.

Coming to an application level use case, suppose there is a situation when you want to abstain a user from continuously firing events, throttleTime can be helpful in such situations. A couple of such scenarios can be :

Now, let’s see some code in action:

<button>Click!</button>
let counter = 0;
const button = document.querySelector('button');
const incrementCounter = () => {
	console.log(counter++);
}
Rx.Observable.fromEvent(button,'click').subscribe(incrementCounter);

Well, the idea behind the above code is pretty simple:

Every time the button is clicked, the observable emits a value and and due to the subscription on this observable, incrementCounter function is called and value of the counter is logged on console.

Now, suppose we want to limit the rate at which counter can be incremented, say once in 2 seconds, we can change our existing code by adding throttleTime operator and passing time 2000ms to it. Here is the modified code:

let counter = 0;
const button = document.querySelector('button');
const incrementCounter = () => {
	console.log(counter++);
}
Rx.Observable.fromEvent(button,'click').throttleTime(2000).subscribe(incrementCounter);

throttleTime in action

throttleTime on click

So when first time you click the button, 0 would be printed and then even if you click the button again multiple times, 1 would be printed only after 2 seconds.

This means even if you click multiple times on the “Click!” button, counter would be incremented and logged only once in 2 seconds.

So how does throttleTime works?

Here is a working demo.

Now, let’s move on to debouncingTime operator. But before we move, lets understand what does the term debounce means. Well, the term debouncing is mostly related to hardware, electrical switches, micro-controllers etc. It is basically a way for eliminating unwanted signals from an input.

A typeahead / autocomplete is the classic use case for debouncing. Now suppose user is typing something we would want to make an API call, to show the suggestions according to the input value entered by the user. But it would be better to make API call in a controlled manner, otherwise we will end up making numerous un-needed calls to the server.

debounceTime is similar to throttleTime except one key difference is that this operator keeps track of the most recent value from the Observable, and emits that only when the defined duration has passed without any other value appearing on the source Observable.

Let’s have a look at the below code:

<input type="text">
const input = document.querySelector('input');
const printInput = (userInput) => {
	console.log(userInput.target.value);
}
Rx.Observable.fromEvent(input,'keyup').subscribe(printInput);

If you run the above code and type anything in the input box, it would be logged on console. But we don’t want to do that. We want to print the user input in a more controlled manner, so that not all values are printed. We just need to add debounceTime operator to the above code.

So our code would look like:

const input = document.querySelector('input');
const printInput = (userInput) => {
	console.log(userInput.target.value);
 }
 Rx.Observable.fromEvent(input,'keyup').debounceTime(1000).subscribe(printInput);

Here is working demo.

So how does debounceTime works?

You, would now be thinking we could have used throttleTime here instead of debounceTime. Have a look at the below images, as they might help clear the confusion:

throttleTime on input

throttleTime

We can notice here that value was emitted once in a second. This was not our intention, as we need the most recent value emitted by the observable in this case.

debounceTime on input

debounceTime

In the above gif you would have noticed that most recent value is emitted and the older value is dropped, which was the intention.

So next time when we have to restrict multiple clicks at a time on a button or have to fetch data on the basis of keyed in value, we know which operators to use!

Follow Me

Github

Twitter

LinkedIn

More Blogs By Me