假设我有两个类,您可以在其中观察一些可观察量。
第一个例子,公共主题:
class EventsPub {
public readonly onEnd = new Subject<void>();
}
第二个例子,具有私有主题和注册方法:
class EventsPriv {
private readonly endEvent = new Subject<void>();
public onEnd(cb: () => void): Subscription {
return this.endEvent.subscribe(cb);
}
}
第一个例子在某种程度上是不安全的,因为任何人都可以调用eventsPub.endEvent.next()
然而,与示例 2 相比,它允许使用管道,这是一个很大的优点,因为开发人员可以使用管道。仅注册第一个活动eventsPub.onEnd.pipe(first()).subscribe(cb)
.
第二个示例也允许一次性订阅,但需要更多代码并且取消订阅也很糟糕。
const subscription = eventsPriv.onEnd(() => {
// logic..
subscription.unsubscribe()
});
从您的角度来看,哪条路是最好的?或者也许有更好的解决方案?
这很大程度上取决于我的个人喜好,但我会这样做:
class EventsPriv {
private readonly endEvent = new Subject<void>();
get endEvent$(): Observable<void> {
return this.endEvent;
}
}
所以在课堂上我会使用endEvent
虽然我仍然可以使用它,例如。在模板中obj.endEvent$ | async
从外部来看,它的行为就像一个 Observable。
请注意,事实上我返回的是同一个实例Subject
。唯一限制外界滥用它的东西obj.endEvent$.next()
是 Typescript 的类型保护。如果我只使用 JavaScript 或者我将其类型转换为any
我可以打电话next
.
这实际上是推荐的暴露方式Subject
s 而不是使用asObservable()
操作员。您可以注意到,RxJS 5 内部到处都使用了这一点。例如,如果您查看repeatWhen
概要:
public repeatWhen(notifier: function(notifications: Observable): Observable): Observable
您可以看到notifier
函数接收一个 Observable 作为参数(您也可以在此处的代码中看到它https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L29 https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L29).
但是如果你查看调用该函数的代码,你会发现它们实际上传递了一个Subject
而不是一个Observable
: https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L114-L115 https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L114-L115.
这已经在 RxJS GitHub 页面上进行了讨论,其原因是性能以及 Typescript 类型防护就足够了。您可以在这些讨论中阅读更多内容:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)