问题
In a lot of codebases using RxJS I seem to come across the pattern of exposing private Subjects
as Observables
via a getter
or normal getObservable()
function. My question is not why .asObservable()
is used, but instead why it seems so commonly wrapped in a getter/factory function?
asObservable() wrapped in getter/factory function
private readonly _engineInfo$ = new Subject<EngineInfo>();
get engineInfo$() { return this._engineInfo$.asObservable(); }
asObservable() as instance variable
private readonly _engineInfo$ = new Subject<EngineInfo>();
public engineInfo$ = this._engineInfo$.asObservable();
Questions
- My undestanding is that
.asObservable()
creates a newObservable
every time that subscribes to theSubject
. Also the createdObservable
is hot and can be subscribed multiple times. Why would one create multiple anonymous instances ofObservable
, (one for each access/subscription), instead of having just oneObservable
, accessed at one class/service, that all observers subscribe to? - Is there a non-obvious advantage to this
getter/factory function
pattern? - Could it be because of garbage collection or testing/mocking advantages?
So far I'm using the instance variable setup from the second example in all services/classes and everything seems to works as expected, also with multiple observers.
回答1:
When to use Subject.prototype.asObservable()
The purpose of this is to prevent leaking the "observer side" of the Subject out of an API. Basically to prevent a leaky abstraction when you don't want people to be able to "next" into the resulting observable.
You never want to return a Subject instance to the calling context. Doing so would be somewhat akin to returning a Deferred object rather than a promise; and, it would leave the Subject open to unanticipated and corrupting usage. As such, when exposing a Subject, you'll probably want to convert it to an Observable first.
To get this working we can use the Rx.Observable.prototype.asObservable()
instance method.
The subject itself is hot/sharable and it acts as a bridge/proxy between the source Observable and many observers, making it possible for multiple observers to share the same Observable execution.
Is there a non-obvious advantage to this getter/factory function pattern?
Nope, not at all since you are Creating a new Observable with this Subject as the source to conceal it from code that uses the Observable.
When to use asObservable() in rxjs?
来源:https://stackoverflow.com/questions/61288259/why-use-the-rxjs-asobservable-getter-factory-function-pattern