rxjs科目应该在课堂上公开吗? [英] Should rxjs subjects be public in the class?
问题描述
假设我有两个课程,你可以观察一些观察者。
Let's say I have two classes, where you can observe over some observables.
第一个例子,公共主题:
First example, with public subject:
class EventsPub {
public readonly onEnd = new Subject<void>();
}
第二个例子,私有主题和注册方法:
Second example, with private subject and registering method:
class EventsPriv {
private readonly endEvent = new Subject<void>();
public onEnd(cb: () => void): Subscription {
return this.endEvent.subscribe(cb);
}
}
第一个例子是不安全的,因为任何人都可以打电话给 eventsPub.endEvent.next()
来自课外并引入副作用,但是,与示例2相比它允许管道,这是一个很大的优势,因为开发人员可以为ex。仅使用 eventsPub.onEnd.pipe(first())注册第一个事件.subsubbe(cb)
。
The first example is somehow unsafe because anyone can call eventsPub.endEvent.next()
from outside the class and introduce side effects, however, comparing to example 2 It allows for pipes, which is a big plus since developers can for ex. register only for the first event with eventsPub.onEnd.pipe(first()).subscribe(cb)
.
第二个例子也允许一次性订阅但需要更多代码和丑陋的取消订阅。
The second example also allows for one-time subscription but requires more code and ugly unsubscribing.
const subscription = eventsPriv.onEnd(() => {
// logic..
subscription.unsubscribe()
});
从您的角度来看,哪种方式最好?或者可能有更好的解决方案?
From your point of view, which is the best way to go? Or maybe there is a better solution?
推荐答案
这很大程度上取决于我个人的偏好,但我会这样做:
This is based a lot on my personal preference but I'd do it like this:
class EventsPriv {
private readonly endEvent = new Subject<void>();
get endEvent$(): Observable<void> {
return this.endEvent;
}
}
所以在课堂上我会用 endEvent
虽然我仍然可以使用它,例如。在 obj.endEvent $ |的模板中async
并且从外部看起来就像一个Observable。
So inside the class I'll use endEvent
while I can still use it eg. in a template with obj.endEvent$ | async
and from the outside it behaves like an Observable.
注意,实际上我正在返回<$ c $的同一个实例C>主题。限制外部世界滥用 obj.endEvent $ .next()
的唯一因素是Typescript的类型保护。如果我只是使用JavaScript或者我将其类型化为任何
我可以调用 next
。
Note, that in fact I'm returning the same instance of Subject
. The only thing that restricts the outside world from misusing it with obj.endEvent$.next()
are Typescript's type guards. If I was using just JavaScript or if I typecasted it to any
I could call next
.
这实际上是推荐的曝光主题
的方式,而不是使用 asObservable()
运营商。您可以注意到这在RxJS 5内部随处使用。例如,如果您查看 repeatWhen
synopsys:
This is actually the recommended way of exposing Subject
s instead of using the asObservable()
operator. You can notice that this is used everywhere internally in RxJS 5. For example if you look at repeatWhen
synopsys:
public repeatWhen(notifier: function(notifications: Observable): Observable): Observable
您可以看到通知程序
函数接收一个Observable作为参数(您可以在此处的代码中看到它 https://github.com/ReactiveX/rxjs/blob/5.5.6/src/ operator / repeatWhen.ts#L29 )。
You can see that the notifier
function receives an Observable as a parameter (you can see it in the code here as well https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L29).
但是如果你查看调用函数的代码,你会发现它们实际上正在通过主题
而不是 Observable
: https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L114 -L115 。
But if you look into the code where the function is called you'll see they are in fact passing a Subject
and not an Observable
: https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L114-L115.
这是d在RxJS GitHub页面上进行了讨论,其原因是性能和Typescript类型保护就足够了。您可以在以下讨论中阅读更多内容:
This has been discussed on RxJS GitHub page and reasons for this are performance and that the Typescript type guards are sufficient. You can read more in these discussions:
https://github.com/ReactiveX/rxjs/issues/2391
这篇关于rxjs科目应该在课堂上公开吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!