Subjects are used for multicasting Observables. This means that Subjects will make sure each subscription gets the exact same value as the Observable execution is shared among the subscribers. You can do this using the Subject class. But rxjs offers different types of Subjects, namely: BehaviorSubject, ReplaySubject and AsyncSubject.
If you think you understand Subjects, read on! Else i would suggest to read my other article about Subjects: Understanding rxjs Subjects.
One of the variants of the Subject is the BehaviorSubject. The BehaviorSubject has the characteristic that it stores the “current” value. This means that you can always directly get the last emitted value from the BehaviorSubject.
There are two ways to get this last emited value. You can either get the value by accessing the
.value property on the BehaviorSubject or you can subscribe to it. If you subscribe to it, the BehaviorSubject will directly emit the current value to the subscriber. Even if the subscriber subscribes much later than the value was stored. See the example below:
There are a few things happening here:
- We first create a subject and subscribe to that with Subscriber A. The Subject then emits it’s value and Subscriber A will log the random number.
- The subject emits it’s next value. Subscriber A will log this again
- Subscriber B starts with subscribing to the subject. Since the subject is a BehaviorSubject the new subscriber will automatically receive the last stored value and log this.
- The subject emits a new value again. Now both subscribers will receive the values and log them.
- Last we log the current Subjects value by simply accessing the
.valueproperty. This is quite nice as it’s synchronous. You don’t have to call subscribe to get the value.
Last but not least, you can create BehaviorSubjects with a start value. When creating Observables this can be quite hard. With BehaviorSubjects this is as easy as passing along an initial value. See the example below:
The ReplaySubject is comparable to the BehaviorSubject in the way that it can send “old” values to new subscribers. It however has the extra characteristic that it can record a part of the observable execution and therefore store multiple old values and “replay” them to new subscribers.
When creating the ReplaySubject you can specify how much values you want to store and for how long you want to store them. In other words you can specify: “I want to store the last 5 values, that have been executed in the last second prior to a new subscription”. See example code below:
There are a few things happening here:
- We create a ReplaySubject and specify that we only want to store the last 2 values
- We start subscribing to the Subject with Subscriber A
- We execute three new values trough the subject. Subscriber A will log all three.
- Now comes the magic of the ReplaySubject. We start subscribing with Subscriber B. Since we told the ReplaySubject to store 2 values, it will directly emit those last values to Subscriber B and Subscriber B will log those.
- Subject emits another value. This time both Subscriber A and Subscriber B just log that value.
As mentioned before you can also specify for how long you wan to store values in the replay subject. Let’s see an example of that:
Again, there are a few things happening here.
- We create the ReplaySubject and specify that we only want to store the last 2 values, but no longer than a 100 ms
- We start subscribing with Subscriber A
- We start emiting Subject values every 200 ms. Subscriber A will pick this up and log every value that’s being emited by the Subject.
- We start subscribing with Subscriber B, but we do that after 1000 ms. This means that 5 values have already been emitted by the Subject before we start subscribing. When we created the Subject we specified that we wanted to store max 2 values, but no longer then 100ms. This means that after a 1000 ms, when Subscriber B starts subscribing, it will only receive 1 value as the subject emits values every 200ms.
While the BehaviorSubject and ReplaySubject both store values, the AsyncSubject works a bit different. The AsyncSubject is aSubject variant where only the last value of the Observable execution is sent to its subscribers, and only when the execution completes. See the example code below:
This time there’s not a lot happening. But let’s go over the steps:
- We create the AsyncSubject
- We subscribe to the Subject with Subscriber A
- The Subject emits 3 values, still nothing hapening
- We subscribe to the subject with Subscriber B
- The Subject emits a new value, still nothing happening
- The Subject completes. Now the values are emitted to the subscribers which both log the value.
The BehaviorSubject, ReplaySubject and AsyncSubject can still be used to multicast just like you would with a normal Subject. They do however have additional characteristics that are very handy in different scenario’s.
Do you consider yourself to be one of the best?
I work for Founda as a Senior front-end developer and we are looking for Senior developers that specialise in Vue and/or Node.
Founda is creating the future of healthcare IT. We are founded by seasoned tech entrepreneurs in January 2019, Founda is a young and well funded company in the health tech & low code / no code space in Amsterdam.
We have been building a technology company using a modern stack with a small team of self-determined developers. We are looking to grow the company with high quality people.
If you think you have what it takes to build the future of Healthcare and you are a European resident. Drop me a line at email@example.com.