Common Observed and startWith Operator

I have a question about multicast observables and unexpected (for me) behavior that I noticed.

const a = Observable.fromEvent(someDom, 'click') .map(e => 1) .startWith(-1) .share(); const b = a.pairwise(); a.subscribe(a => { console.log(`Sub 1: ${a}`); }); a.subscribe(a => { console.log(`Sub 2: ${a}`) }); b.subscribe(([prevA, curA]) => { console.log(`Pairwise Sub: (${prevA}, ${curA})`); }); 

So there is a common observable a that emits 1 for each click event. -1 is emitted due to the startWith operator. Observable b simply creates a new observable by combining the last two values ​​from a.

My expectation was:

 [-1, 1] // first click [ 1, 1] // all other clicks 

What I observed was:

 [1, 1] // from second click on, and all other clicks 

I noticed that the value -1 is emitted immediately and consumed by Sub 1 before even Sub 2 subscribes to the observable, and since a is multicast, Sub 2 is late for the participant.

Now I know that I can multicast through BehaviourSubject and not use the startWith operator, but I want to understand an example of using this script when I use startWith and multicast via share.

As far as I understand, whenever I use .share () and .startWith (x), only one subscriber will be notified of the startWith value, since all other subscribers subscribe after emitting the value.

So, is this the reason for multicasting through some special item (Behavior / Replay ...) or am I missing something in this startWith / share script?

Thanks!

+6
source share
1 answer

This is really the right behavior.

.startWith() allocates its value for each new subscriber, and not just for the first. The reason b.subscribe(([prevA, curA]) never gets it is because you are using multicast with .share() (aka .publish().refCount() ).

This means that the first a.subscribe(...) forces .refCount() subscribe to its source and will remain a subscriber (note that Observable .fromEvent(someDom, 'click') never terminates).

Then, when you finally call b.subscribe(...) , it will only subscribe to Subject inside .share() and will never go through .startWith(-1) because it is multicast and is already signed in .share() .

+8
source

Source: https://habr.com/ru/post/1014673/


All Articles