Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJS combineAll Operator, explanation

I'm trying to understand how does the combineAll operator work. I'm using the following example from the official documentation:

import { take, map, combineAll } from 'rxjs/operators';
import { interval } from 'rxjs';

const source$ = interval(1000).pipe(take(2));

const example$ = source$.pipe(
  map(val =>
    interval(1000).pipe(
      map(i => `Result (${val}): ${i}`),
      take(5)
    )
  )
);

example$
  .pipe(combineAll())
  .subscribe(console.log);

The output is then :

["Result (0): 0", "Result (1): 0"]
["Result (0): 1", "Result (1): 0"]
["Result (0): 1", "Result (1): 1"]
["Result (0): 2", "Result (1): 1"]
["Result (0): 2", "Result (1): 2"]
["Result (0): 3", "Result (1): 2"]
["Result (0): 3", "Result (1): 3"]
["Result (0): 4", "Result (1): 3"]
["Result (0): 4", "Result (1): 4"]

Trying to figure why, I made this simple scheme:

combineAll Scheme

From the documentation, I read that each time any of the inner Observable emits a value, then this emitted value is combined by the last value of all the other inner observables.

In the scheme above, we can see that 10 values are emitted during time by the inner Observables, so I was expecting to get an output with 10 values over the time, but it's 9.

Also, in the first line of the output :

["Result (0): 0", "Result (1): 0"]) 

Does the 0 of 'Result (1): 0' correspond to a null value? Because Observable 'inner 2' has not yet emitted anything?

To finish here is what I was expecting as output :

["Result (0): 0", "Result (1): 0"]
["Result (0): 1", "Result (1): 0"]
["Result (0): 1", "Result (1): 0"]
["Result (0): 2", "Result (1): 0"]
["Result (0): 2", "Result (1): 1"]
["Result (0): 3", "Result (1): 1"]
["Result (0): 3", "Result (1): 2"]
["Result (0): 4", "Result (1): 2"]
["Result (0): 4", "Result (1): 3"]
["Result (0): 4", "Result (1): 4"]

It's obviously wrong but I don't find my mistake, could someone explain?

like image 767
Bil5 Avatar asked Jul 19 '17 05:07

Bil5


People also ask

What are combination operators available in RxJS?

The combination operators allow the joining of information from multiple observables. Order, time, and structure of emitted values is the primary variation among these operators.

How do you wait for two observables?

While zip method emits the emitted items in sequence order. For example if observable #1 emits its 3rd item and observable #2 has emitted its 5th item. The result using zip method will be the 3rd emitted values of both observables . In this situation the result using combineLatest will be the 5th and 3rd.

How do I combine two observables RxJS?

The RxJS merge() operator is a join operator that is used to turn multiple observables into a single observable. It creates an output Observable, which concurrently emits all values from every given input Observables.


1 Answers

Consider that combineAll:

flattens an Observable-of-Observables by applying combineLatest when the Observable-of-Observables completes.

And that combineLatest;

will actually wait for all input Observables to emit at least once.

So the first emission from the combineAll observable that includes the first value of the "Inner 1" observable is not going to happen until the "Inner 2" observable emits its first value. So there will only be nine emissions - not ten.

like image 76
cartant Avatar answered Oct 05 '22 09:10

cartant