Saturday 19 October 2019

Hot vs Cold Observables

Having read some of the multiple articles on the Hot vs Cold observables thing like this, I used to think that I have a good understanding of it, but the other day I came across a question in StackOverflow that quite confused me. I did my own test to verify that it really worked like that.

import { Observable, Subject, ReplaySubject, from, of, range } from 'rxjs';
import { map, filter, switchMap, flatMap, tap, mapTo} from 'rxjs/operators';

const subject1 = new Subject();

let ob1 = subject1.pipe(
    tap(it => console.log("tap: " + it)),
    map (it => {
  console.log("map: " + it);
  return it * 2;
 })
);

ob1.subscribe(it => console.log(it + " received in subscription 1"));
ob1.subscribe(it => console.log(it + " received in subscription 2"));

subject1.next(20);

We get this output:

tap: 20
map: 20
40 received in subscription 1
tap: 20
map: 20
40 received in subscription 2

I would have expected the ouput to be like this:

tap: 20
map: 20
40 received in subscription 1
40 received in subscription 2

I'd never checked how pipe and operators are implemented, so I was thinking that when we pipe several operators a sort of chain is created, so that when a subscribe is run, the different observables are created and linked, but this chain of observables would be created only once, regardless of how many subscription we were doing, so we would have:

subject -> tap Observable -> map Observable -> subscriber 1
                                           |
                                           |-> subscriber 2

Reading this article about creating your custom operators has helped me to understand that the above chain is created each time we call subscribe, so what we really get is this:

subject -> tap Observable -> map Observable -> subscriber 1
       |
       |-> tap Observable2 -> map Observable2 -> subscriber 2

No comments:

Post a Comment