I have learned of two different ways of making an Observable. First one was with a Subject, like so:
// file A
const message$ = new Subject();
// file B
message$.subscribe( (message) => console.log(message) );
// file C
message$.next("Hello there!");
This method of creating an Observable allows me to have a way to exchange data from file B to file C.
The second way is via the Observable class, like so:
// file A
const click$ = new Observable( function(observer) {
//Alternatively, I can use Observable.create()
document.addEventListener('click', (e) => observer.next(e));
});
// file B
click$.subscribe( (cl) => console.log(cl) );
The main difference that I can gather between the Subject way and the Observable way is that I am not sure how to have some sort of communication between some file C, to the subscribers of the Observable. Basically, click$ does not have a .next()
method, and the observer methods are in the function that we pass to the observable.
Other than this difference in behavior, is there another difference between observables made with Subject, and those made with Observable
A Subject
is both Observable
and Observer
at the same time. That makes it so tempting to use, because you get a reference to an Observer
that you can pass around in your code and emit items from wherever you want. However, that increases the error-proneness of your code by a lot, as you switch from a declarative definition of your Observable to a imperative one.
Generally speaking, you should use Observable creation functions (of, from, create) wherever possible. I'd say most cases can be solved without Subjects. There is a steep learning-curve though, as you must get to know most of the Observable creation functions in order to follow that pattern.
Subject might come more natural to developers who are used to code imperatively (that is: with a script language like JS), as it kind of resembles a simple wrapper object for a callback function. And one might ask, why is there a Subject anyway if its not desirable.
According to this article, Subjects are to be used in one case only:
To generate a hot observable imperatively and statefully, without any direct external source.
In short, that means: Use Subject when you don't have any external source (like an Observable, Promise or Event) and need to multicast the state of a class from inside a function. You shouldn't expose that Subject to others, though!
I suggest reading this article to you, it will clear up things.
Subject implements both the Observable and the Observer interface.
Implementing the Observable interface means, among other things, that you can subscribe
to a Subject.
Implementing the Observer interface means, among other things, that with a Subject you can call the methods next
error
and complete
.
You create Observables using Subject in the case you want to control programmatically the flow of events of that Observable, which is the case you mentioned of managing communication between C and B.
The relation between Subject
and Observable
goes like this:
class Observable {}
class Subject extends Observable {}
Subject
implements Subscriber
interface. So you can use Subject
as a Subscriber
(Observable
cannot be used like this):
const subj = new Subject()
observable.subscribe(subj)
Subject
can hide it's Subscriber
interface by calling asObservable
method - turning Subject
into plain Observable
;
I generally use Subject
when my code is going to generate events and I use Observable
when I already have some source of events
For example using Subject as a queue:
const queue = new Subject();
queue.pipe(
concatMap(doStuff)
).subscribe()
queue.next('do this')
queue.next('do that')
or using Subject as a signaller to stop other Observable
const stop = new Subject();
someObservable.pipe(
map(x => x + 1)
takeUntil(stop)
)
// somewhere in my code
stop.next()
Other than this difference in behavior, is there another difference between observables made with Subject, and those made with Observable
I wouldn't say there are differences - It is more like Subject
is a complement to plain Observable
- allowing us to do more things when needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With