‘share‘ and ‘shareReplay‘ are higher-order observable operators in RxJS that control the behavior of an observable in relation to its subscribers. They’re used to manage multicasting, i.e., broadcasting the same sequence of notifications to multiple subscribers.
First, let’s discuss each operator individually, and then we’ll look at the differences between them and when to use each.
1. ‘share‘ operator
The ‘share‘ operator is a shorthand for the ‘multicast(() => new Subject())‘ and ‘refCount()‘ composition. A Subject is a special kind of observable that can act as both an observer and an observable. The ‘share‘ operator makes the source observable hot, allowing multiple subscribers to share the same subscription.
Consider the following example:
import { interval } from 'rxjs';
import { share, take } from 'rxjs/operators';
const source$ = interval(1000).pipe(take(5), share());
// First subscriber
source$.subscribe((val) => console.log(`Subscriber 1: ${val}`));
setTimeout(() => {
// Second subscriber
source$.subscribe((val) => console.log(`Subscriber 2: ${val}`));
}, 2000);
In this example, both subscribers share the same subscription to the source. ‘Subscriber 1‘ starts receiving values immediately, and after 2 seconds ‘Subscriber 2‘ starts receiving values. Since they’re sharing the same subscription, ‘Subscriber 2‘ misses the first two values.
2. ‘shareReplay‘ operator
The ‘shareReplay‘ operator is a variant of the ‘share‘ operator that shares not only the subscription but also broadcasts the notifications of the source observable to new subscribers from a replay buffer. This buffer can store a specific number of values, and when a new subscriber is added, it will receive the notifications from the buffer.
Consider the following example:
import { interval } from 'rxjs';
import { shareReplay, take } from 'rxjs/operators';
const source$ = interval(1000).pipe(take(5), shareReplay(2));
// First subscriber
source$.subscribe((val) => console.log(`Subscriber 1: ${val}`));
setTimeout(() => {
// Second subscriber
source$.subscribe((val) => console.log(`Subscriber 2: ${val}`));
}, 2000);
In this example, the source observable is being shared with a replay buffer size of 2. When ‘Subscriber 2‘ starts to listen at 2 seconds, it receives the last two values from the buffer and then continues to receive real-time values along with ‘Subscriber 1‘.
Now let’s summarize the differences between ‘share‘ and ‘shareReplay‘:
1. The ‘share‘ operator shares the subscription to the source observable, but the late subscribers miss the notifications that happened before they were connected. In contrast, the ‘shareReplay‘ operator shares the subscription and broadcasts the notifications from a replay buffer to late subscribers.
2. The ‘shareReplay‘ operator can store a specific number of values in a buffer or a set window of time. The ‘share‘ operator does not cache any values.
So, when should you use each operator?
- Use the ‘share‘ operator when you want to share a single subscription between multiple subscribers without caching any previous notifications. It is useful when you only want subscribers to receive notifications after they’ve connected, and they do not need any historical data.
- Use the ‘shareReplay‘ operator when you want to share a single subscription and also provide late subscribers with previous notifications from a replay buffer. It is useful when you want to provide the subscribers with the latest value or a preset history to help them start with context.