RxJS: Throttle explained

Posted by Tomasz Smykowski on

RxJS stands for Reactive Extensions for JavaScript. It is a great library to handle flow of items received by your application. Today you will learn what is one of the most commonly used RxJS operator: throttle.

The documentation offers a nice diagram with circles that is self-explanatory:

 

But what does it really mean? Let's forget about the diagram for a moment.

The analogy

Imagine that a guard protects the entrance to a temple where a stone of power is kept. Your team has to go inside to get it. Near the gates there is a secret tunnel that leads inside the fortress. However, the problems is that when the guard notices anything, he goes to see what happens.

So only one of your team can go inside the tunnel. The guard looks around, and you all wait for some time. When the guard goes away, the next person can go inside.

If you want to succeed you have to follow this until all your team members are inside. If you do not wait, your team member will be captured by the guard.

Throttle works like the guard of the secret entry. One person entering the tunnel triggers a guard, who blocks entry for a some time.

It looks like this:

How to translate this analogy to programming? Why an app you write should block an entry of anything for a specific period of time? Rate-limit events?

The example

There are various scenarios when it is useful. Especially when you want to react to the first incoming event, and then ignore following for a period of time. Let me tell you about one, that is pretty common.

Did you notice that some people double click on buttons on the internet? It is a behavior that is derived from how folders and files are opened on some operating systems like Windows. However on the internet buttons react to a single click. Also, some people click again, when the UI does not indicate the previous click caused any reaction of the UI (it was ignored).

So let's say a user wants to download a 100MB file from a file sharing service. When he clicks the button twice, a file will be downloaded twice. It will spend his brand witch, and put an overhead on your infrastructure. So you decide to make sure to fix it.

You decide to react on the first click of a user, and then ignore his clicks for 1 second (1000 ms). Since the double click usually takes 500ms, that way the second click will be ignored. Also, that way the UI will have some time to react to the action, for example by showing a progress bar.

The logic you want to introduce to your app looks like this:

  1. When the user clicks a button:
    - start downloading the file
    - ignore following button clicks for 1 second

The formal way to write it down with RxJS like this:

downloadFileClicked
   .pipe(

      throttle(
         ev => interval(1000)
      )

   )
   .subscribe(
      x => startDownloadingFile(x)
   );

As you can see it is pretty complex syntax. It is because RxJS offers more operators than throttle and ways to combine them. You can think of pipe section as a decision-making how to handle incoming events, and subscribe what to do with events that pipe returns.

There are other operators you can use in the pipe section. However, there are two interesting things about throttle I want to share with you before this article finishes.

Interesting facts

Throttle accepts a configuration containing leading and trailing boolean values.  So what do they do?

Leading decides if the first item should be handled. On default, it is set to true, so that a new item is handled. If you set it to false, the first item won't be emitted. It does not impact behavior for following items. They will be ignored for some time as usual.

Trailing decides, if last item received in the "ignoring" phase should wait and be emitted when ignorance time will end. What suggests that there had to be also a first event that triggered "ignoring" phase.

If you want to work with time intervals, you may find throttleTime better for you. The documentation contains an example how to rate-limit clicks and also an example how to detect a double click to handle it (contrary to our example). The example also shows how leading and trailing settings can be of a help.

Summary

Throttle is a great RxJS operator to rate-limit events, items etc. Remember about it every time you have to react immediately, and ignore for some time, or detect that two consecutive events occurred in a given period of time.