class 中的 rxjs 科目应该是 public 吗?
Should rxjs subjects be public in the class?
假设我有两个 classes,您可以在其中观察一些 observables。
第一个示例,public 主题:
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);
}
}
第一个示例在某种程度上是不安全的,因为任何人都可以从 class 外部调用 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;
}
}
所以在 class 中,我将使用 endEvent
,同时我仍然可以使用它,例如。在带有 obj.endEvent$ | async
的模板中,从外部看它的行为就像一个 Observable。
请注意,实际上我返回的是 Subject
的同一个实例。唯一限制外界将其与 obj.endEvent$.next()
一起滥用的是 Typescript 的类型保护。如果我只使用 JavaScript 或者如果我将它转换为 any
我可以调用 next
.
这实际上是公开 Subject
而不是使用 asObservable()
运算符的推荐方式。您会注意到,这在 RxJS 5 内部随处使用。例如,如果您查看 repeatWhen
synopsys:
public repeatWhen(notifier: function(notifications: Observable): Observable): Observable
您可以看到 notifier
函数接收一个 Observable 作为参数(您也可以在此处的代码中看到它 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.
这已经在 RxJS GitHub 页面上讨论过,原因是性能和 Typescript 类型保护就足够了。您可以在这些讨论中阅读更多内容:
假设我有两个 classes,您可以在其中观察一些 observables。
第一个示例,public 主题:
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);
}
}
第一个示例在某种程度上是不安全的,因为任何人都可以从 class 外部调用 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;
}
}
所以在 class 中,我将使用 endEvent
,同时我仍然可以使用它,例如。在带有 obj.endEvent$ | async
的模板中,从外部看它的行为就像一个 Observable。
请注意,实际上我返回的是 Subject
的同一个实例。唯一限制外界将其与 obj.endEvent$.next()
一起滥用的是 Typescript 的类型保护。如果我只使用 JavaScript 或者如果我将它转换为 any
我可以调用 next
.
这实际上是公开 Subject
而不是使用 asObservable()
运算符的推荐方式。您会注意到,这在 RxJS 5 内部随处使用。例如,如果您查看 repeatWhen
synopsys:
public repeatWhen(notifier: function(notifications: Observable): Observable): Observable
您可以看到 notifier
函数接收一个 Observable 作为参数(您也可以在此处的代码中看到它 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.
这已经在 RxJS GitHub 页面上讨论过,原因是性能和 Typescript 类型保护就足够了。您可以在这些讨论中阅读更多内容: