DEV Community

DEV
DEV

Posted on • Updated on

RxJS Subjects

Subjects are multicast. An RxJS Subject is a special type of Observable that allows values to be multicasted to many Observers. A Subject is an Observable and Observer. There are also a few specializations of the Subject type: BehaviorSubject, ReplaySubject, and AsyncSubject.

Subject

Subject does not return the current value on Subscription. It triggers only on .next(value) call and return/output the value.
The below code snippet will loss value 1 as no one is subscribed to the sub yet. After that A subscribed to sub and it will wait untill sub emits some value. When sub emit value 2 it will console log A - 2 and so on.

const sub = new Subject<number>();
sub.next(1); // It's lost as no one is observing sub currently
// A start observing sub
sub.subscribe({
  next: (v) => console.log(`A - ${v}`)
});
sub.next(2); // A - 2
// B start observing sub
sub.subscribe({
  next: (v) => console.log(`B - ${v}`)
});
sub.next(3); // A - 3 , B - 3
// C start observing sub
sub.subscribe({
  next: (v) => console.log(`C - ${v}`)
});
setTimeout(() => { 
  sub.next(4); // A - 4, B - 4, C - 4
},5000);
Enter fullscreen mode Exit fullscreen mode

BehaviorSubject

BehaviourSubject will return the initial value or the current value on Subscription.
The below code snippet where we have bsub a BehaviorSubject with initial value as 0 . So, when A subscribed to it - it will receive the initial value. In case of C , when it subscribed to bsub it will received the current value which is 3 and will console log C - 3

const bsub = new BehaviorSubject(0);
bsub.subscribe({
  next: (v) => console.log(`A - ${v}`)
});
bsub.next(1);
bsub.subscribe({
  next: (v) => console.log(`B - ${v}`)
});
bsub.next(3);
bsub.subscribe({
  next: (v) => console.log(`C - ${v}`)
});
Enter fullscreen mode Exit fullscreen mode

ReplaySubject

ReplaySubject works some what simillar as BehaviourSubject but It will not tak any initial value.
It’s take a numeric parameter which acts as buffer for the number of old values it will hold. So, when B subscribed to rsub it recived 2, 3, 4 as buffer size is 3. Therefore 1 is lost. It will also recive 5 later when it emit.

const rsub = new ReplaySubject(3);
rsub.next(1);
rsub.next(2);
rsub.next(3);
rsub.next(4);
rsub.subscribe({
  next: (v) => console.log(`B - ${v}`)
});
rsub.next(5);
Enter fullscreen mode Exit fullscreen mode

AsyncSubject

The AsyncSubject is a variant where only the last value of the Observable execution is sent to its observers, and only when the execution completes.

const asub1 = new AsyncSubject();
const asub2 = new AsyncSubject();

asub1.next(1);
asub2.next(1);
asub1.subscribe({
  next: (v) => console.log(`A - ${v}`)
});
asub1.complete(); // A - 1
asub2.next(2);
asub2.next(3);
asub2.subscribe({
  next: (v) => console.log(`B - ${v}`)
});
asub2.next(4);
asub2.complete(); // B - 4
Enter fullscreen mode Exit fullscreen mode

Checkout all the above code in action at https://stackblitz.com/edit/kdev-rxjs-subjects

Top comments (0)