What does RxJS.Observable debounce do?

14,037

Solution 1

Debounce will emit a value after a specified time interval has passed without another value being emitted.

Using simple diagrams the following may provide greater help:

Stream 1 | ---1-------2-3-4-5---------6----

    after debounce, the emitted stream looks like as follows:

Stream 2 | ------1-------------5---------6-

The intermediate items (in this case, 2,3,4) are ignored.

An example is illustrated below:

var Rx = require('rx-node');
var source = Rx.fromStream(process.stdin).debounce(500);
var subscription = source.subscribe(
    function (x) {
        console.log('Next: %s', x);
    }
);

I used node to illustrate this... assuming you have node installed, you can run it by typing

$node myfile.js  (where the aforementioned code is in myfile.js)

Once this node program is started you can type values at the console -- if you type quickly items are ignored, and if type intermittently fast and slow items will appear after a gap in typing (in the example above I have 500ms) at the console ("Next: ")

There is also some excellent reference material at https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/debounce.md

Solution 2

Long story short: debounce waits for X time that the stream isn't emitting any new value, then let the latest value pass.

Long story: Once a value is emitted, debounce will pause its emission for X time to see if another value is emitted, in fact blocking the stream during this time. If a new value is emitted during the debounce time then the timer is restarted and debounce waits again for the full time. If its timer expires without any new value being emitted, it let the latest value pass.

Let's say that you want to add autocomplete to an input box. If the user insert "a" you may want to show him the choices "acorn, alaska", but if the user right after press "l" you would propose just "alaska". In this case it's better to wait for the user to stop pressing the keyboards to avoid doing unnecessary work. debounce it's the right tool here: it waits for X time the the stream isn't emitting any new value

Solution 3

.debounce() produces the last received value if no values were received within the specified interval.

It means that as soon as you click within a second - nothing will be produced.

If you want to throttle values to be emitted no more frequent than every second you need to use .sample(1000) instead.

Share:
14,037

Related videos on Youtube

Adrian
Author by

Adrian

Just in love with functional programming.

Updated on January 23, 2020

Comments

  • Adrian
    Adrian over 4 years

    Can anybody explain in plain English what RxJS Observable debounce function does?

    I imagine it emits an event once in a while depending on the parameters, but my code below doesn't work as I expected.

    var x$ = Rx.Observable.fromEvent(window, 'click')
        .map(function(e) {return {x:e.x, y:e.y};})
        .debounce(1000)
        .subscribe(function(el) {
          console.log(el);
        });
    

    and the JsBin version.

    I expected that this code would print one click once per second, no matter how fast I am clicking. Instead it prints the click at what I think are random intervals.

    • Brandon
      Brandon about 9 years
      FYI the rxmarbles website can help. It is a work in progress and doesn't have all of the operators, but it does have debounce :)
    • zerkms
      zerkms about 9 years
      @Brandon there is a link in my answer :-)
  • Brandon
    Brandon about 9 years
    throttileFirst is another good choice: When you first click, it emits the click event immediately, but then ignores all clicks for the next X milliseconds.
  • zerkms
    zerkms about 9 years
    @Brandon oh there are so many different operators available. Thanks
  • Adrian
    Adrian about 9 years
    This answer helped to understand debounce whereas the previous one offered the solution to my problem.
  • zerkms
    zerkms about 9 years
    @Adrian this answer reproduces exactly the same diagram I provided a link to.
  • Adrian
    Adrian about 9 years
    Indeed. I looked a lot at rxmarbles before asking the question. That's why I asked for plain English.