Tomas Mikula logo

Tomas Mikula

Demystifying RxJS: ‘share’​ vs ‘shareReplay’​ operators

Facebook
Twitter
LinkedIn

If you use RxJS in your projects, you may have come across the share and shareReplay operators. While both operators are used to share a single execution of a source Observable with multiple subscribers, they have some important differences.

The share and shareReplay operator in RxJS is used to share a single subscription to an observable among multiple subscribers. It allows multiple subscribers to observe the same stream of events, while ensuring that the underlying observable is only subscribed to once.

The share operator works by returning a new observable that is connected to the source observable through a special type of subject known as a ConnectableObservable. This subject allows multiple subscribers to be attached to it, while only subscribing to the source observable once.

‘share’ operator

The share operator can be used to share a source Observable among multiple subscribers without caching its values.

Here’s an example:

const source = of(1, 2, 3).pipe(
  tap(val => console.log(`Source emitted ${val}`)),
  share()
); 

source.subscribe(val => console.log(`Subscriber 1 received ${val}`));
source.subscribe(val => console.log(`Subscriber 2 received ${val}`));

// Results
Source emitted '1'
'Subscriber 1' received '1'
Source emitted '2'
'Subscriber 1' received '2'
Source emitted '3'
'Subscriber 1' received '3'

Source emitted '1'
'Subscriber 2' received '1'
Source emitted '2'
'Subscriber 2' received '2'
Source emitted '3'
'Subscriber 2' received '3'

As you can see, each subscriber receives the same values from the source, but the source Observable is executed each time a new subscriber subscribes. Basically, Subscriber 2 got all values as well.

‘shareReplay’ operator

The shareReplay operator, on the other hand, not only shares the source Observable, but also caches its values and replays them to each new subscriber. This can be useful when you want to ensure that subscribers receive the latest values from the source, even if they subscribe after the source has completed.

Here’s an example:

const source = of(1, 2, 3).pipe(
  tap(val => console.log(`Source emitted ${val}`)),
  shareReplay(1)
);

source.subscribe(val => console.log(`Subscriber 1 received ${val}`));

// We delay second observable
setTimeout(() => {
  source.subscribe(val => console.log(`Subscriber 2 received ${val}`));
}, 1000);

// Results
Source emitted '1'
'Subscriber 1' received '1'
Source emitted '2'
'Subscriber 1' received '2'
Source emitted '3'
'Subscriber 1' received '3'

'Subscriber 2' received '3'

In this example, shareReplay is set to cache 1 value – shareReplay(1), so Subscriber 2 will receive the latest value emitted by the source (in this case, 3).

Conclusion

In summary, the main difference between share and shareReplay is that share shares a source Observable without caching its values, while shareReplay shares the source Observable and caches its values to replay to new subscribers. It is a powerful operator for optimizing the performance of your RxJS observables, by reducing the overhead of multiple subscriptions to the same observable.

Just like sharing is caring, the share operators helps you share your observables with multiple subscribers in a controlled and efficient manner, without having to worry about who gets what and when.

It’s like sharing your favourite pizza toppings with your friends – you only want to order one pizza, but you want everyone to have a chance to enjoy the toppings they love. The share operators helps you do the same thing with observables, so you can all enjoy the tasty bits of data together!

Facebook
Twitter
LinkedIn

Want more valuable tips?

Continue reading