Home > Software design >  RxJS - Shared Observables doesn't share observable value
RxJS - Shared Observables doesn't share observable value

Time:09-27

Please have a look at here
I have an observable to which I am subscribing two times, once in the normal flow and the other in a forkJoin, I have pipe(share()) to the observable and still it’s calling the promise inside that two times, instead of calling it once and sharing the value.

CodePudding user response:

I'm not really sure of what i'm about to say but well... it looks like the new promise in fn create a side effect that retrigger the subscription of fn2. Using a normal observable in fn seems to work. I can't really explain this behaviour so if someone has something interesting to say, leave a comment !

import { defer, forkJoin, from, of } from 'rxjs';
import { share } from 'rxjs/operators';

// Share isn't necessary here since you're subscribing only once to this observable
// let fn = defer(() => of([1, 2]));
let fn = defer(() => new Promise((x) => x(1)));

let fn2 = defer(() => from(
  new Promise((x) => {
    console.log('in');
    x(1);
  })
)).pipe(share());

fn2.subscribe((x) => console.log('[fn2] sub1'));
fn2.subscribe((x) => console.log('[fn2] sub2'));

forkJoin([fn]).subscribe((x) => {
  // hypothesis : new promise is created since it's another context (subscribe are async)
  // uncomment the first fn obs and there's no double 'in' in the console
  fn2.subscribe((x) => console.log('sub'));
});

CodePudding user response:

The behavior you are seeing is partially explained by the following part of the docs:

[share] Returns a new Observable that multicasts (shares) the original Observable. As long as there is at least one Subscriber this Observable will be subscribed and emitting data. When all subscribers have unsubscribed it will unsubscribe from the source Observable.

The subscription is shared as long as there are subscribers. However, in your example observable using of, the observable emits and completes immediately causing subscribers to be unsubscribed. When the second subscription happens, there are no other subscribers, so it fires the promise again.

To avoid this, you can use shareReplay to "replay" the prior emission to new subscribers.

You can see this behavior with this StackBlitz.

  • Related