Subject is an Observable, and also it is an Observer.
Ex:
// Create a Subject
const subject = new Subject();
// It is an Observable
// => subject can be subscribed to with an Observer
subject.subscribe(
val => console.log(val),
err => console.log(err),
() => console.log('complete'),
);
// It is an Observer
// => it can emit values through next(val), error(vale), and complete()
subject.next(1);
subject.next(2);
subject.complete();
Result:
1
2
complete
Unlike plain Observable, Subjects are multicast.
Ex:
// Create a Subject
const subject = new Subject();
// Subscribe it by Subscriber A
subject.subscribe(
val => console.log('A => ', val),
err => console.log(err),
() => console.log('A => complete'),
);
// Subscribe it by Subscriber B
subject.subscribe(
val => console.log('B => ', val),
err => console.log(err),
() => console.log('B => complete'),
);
// Emit an random value
subject.next(Math.floor(Math.random() * 100));
subject.complete();
// Create a plain Observable
const plainObservalbe$ = new Observable(observer => {
// Emit an random value
observer.next(Math.floor(Math.random() * 100));
observer.complete();
});
// Subscribe it by Subscriber C
plainObservalbe$.subscribe(
val => console.log('C => ', val),
err => console.log(err),
() => console.log('C => complete'),
);
// Subscribe it by Subscriber D
plainObservalbe$.subscribe(
val => console.log('D => ', val),
err => console.log(err),
() => console.log('D => complete'),
);
Result:
A => 17
B => 17
A => complete
B => complete
C => 75
C => complete
D => 56
D => complete
According to the result above, subscribing subject will get the same value because it is multicast.
On the other hand, two plain Observable subscribers have their own independent setup and execution. So they got the different value.
Why we should use asObservable() function of a subject
Since Subjects are both Observables and Observers, not only they can be subscribed to, but also they can emit values through .next(). In order to prevent being misused publicly (such everyone can emit the new value through .next()), we can use asObservable() to wrap it. Then people only can subscribe to it and have no ability to emit new values anymore. Refer to this stackoverflow.
Ex:
// Create a Subject and keep it as a private scope
const subject = new Subject();
// Creates a new Observable with this Subject as the source.
// And it can be shared as public scope
const subject$ = subject.asObservable();
subject$.subscribe(
val => console.log(val),
err => console.log(err),
() => console.log('complete'),
);
// It is an observer
// => it can emit values through next(val), error(vale), and complete()
subject.next(1);
subject.next(2);
subject.complete();
Result:
1
2
complete
No comments:
Post a Comment