Subject
- A subscriber will only get published values thereon-after the subscription is made.BehaviorSubject
- New subscribers get the last published value OR initial value immediately upon subscription.ReplaySubject
- New subscribers get the last1-n
published value(s) immediately upon subscription (only if previously emitted).
- Subject: On subscribing it always gets the data which is pushed after it's subscription i.e. previous pushed values are not received.
const mySubject = new Rx.Subject();
mySubject.next(1);
const subscription1 = mySubject.subscribe(x => {
console.log('From subscription 1:', x);
});
mySubject.next(2);
const subscription2 = mySubject.subscribe(x => {
console.log('From subscription 2:', x);
});
mySubject.next(3);
subscription1.unsubscribe();
mySubject.next(4);
With this example, here’s the result that’ll be printed in the console:
From subscription 1: 2
From subscription 1: 3
From subscription 2: 3
From subscription 2: 4
Note how subscriptions that arrive late are missing out on some of the data that’s been pushed into the subject.
- Replay subjects: can help by keeping a buffer of previous values that will be emitted to new subscriptions.
Here’s a usage example for replay subjects where a
buffer of 2 previous values
are kept and emitted on new subscriptions:const mySubject = new Rx.ReplaySubject(2);
mySubject.next(1);
mySubject.next(2);
mySubject.next(3);
mySubject.next(4);
mySubject.subscribe(x => {
console.log('From 1st sub:', x);
});
mySubject.next(5);
mySubject.subscribe(x => {
console.log('From 2nd sub:', x);
});
Here’s what that gives us at the console:
From 1st sub: 3
From 1st sub: 4
From 1st sub: 5
From 2nd sub: 4
From 2nd sub: 5
- Behavior subjects: are similar to replay subjects, but will re-emit only the last emitted value, or a default value if no value has been previously emitted:
const mySubject = new Rx.BehaviorSubject('Hey now!');
mySubject.subscribe(x => {
console.log('From 1st sub:', x);
});
mySubject.next(5);
mySubject.subscribe(x => {
console.log('From 2nd sub:', x);
});
And the result:
From 1st sub: Hey now!
From 1st sub: 5
From 2nd sub: 5
--------------Another discussion---------------------------
Subject
- a subscriber will only get published values that were emitted after the subscription. Ask yourself, is that what you want? Does the subscriber need to know anything about previous values? If not, then you can use this, otherwise choose one of the others. For example, with component-to-component communication. Say you have a component that publishes events for other components on a button click. You can use a service with a subject to communicate.BehaviorSubject
- the last value is cached. A subscriber will get the latest value upon initial subscription. The semantics for this subject is to represent a value that changes over time. For example a logged in user. The initial user might be an anonymous user. But once a user logs in, then the new value is the authenticated user state.TheBehaviorSubject
is initialized with an initial value. This is sometimes important to coding preference. Say for instance you initialize it with anull
. Then in your subscription, you need to do a null check. Maybe OK, or maybe annoying.ReplaySubject
- it can cache up to a specified number of emissions. Any subscribers will get all the cached values upon subscription. When would you need this behavior? Honestly, I have not had any need for such behavior, except for the following case:If you initialize aReplaySubject
with a buffer size of1
, then it actually behaves just like aBehaviorSubject
. The last value is always cached, so it acts like a value changing over time. With this, there is no need for anull
check like in the case of theBehaviorSubject
initialized with anull
. In this instance, no value is ever emitted to the subscriber until the first publishing.
So it really comes down to the behavior you are expecting (as for which one to use). Most of the time you will probably want to use a
BehaviorSubject
because what you really want to represent is that "value over time" semantic. But I personally don't see anything wrong with the substitution of ReplaySubject
initialized with 1
.
No comments:
Post a Comment