angular - 从 ReplaySubject 退订返回 asObservable();
问题描述
标题
如果您基本上有相同的问题并且您的上下文是 Angular,您可能需要阅读答案中的所有评论以获取更多上下文。
这个问题的简短版本
这样做时let observe$ = someReplaySubject.asObservable()
,我们不再需要取消订阅observe$
吗?换句话说,我们可以let observe$ = someReplaySubject.asObservable()
从多个 Angular 组件实例调用而不用担心从notify
实例到对应的连接Observable
吗?
假设
如果我们有一个ReplaySubject<Todo[]>
实例(让我们调用它rxTodo
,然后我们通过执行以下操作从 Angular 组件订阅它:
let todoObs$:Observable<Todo[]> = rxTodo$.asObservable()
那么即使组件被销毁,todoObs$
在每个组件中创建的引用也会悬空,直到组件本身被销毁。
背景
我正在尝试Store
Angular 的 API,并且我有一个重播主题,可以广播对商店切片的更改。这是允许订阅发生的方法(notifyCount 跟踪订阅,因此如果没有订阅,我们就不会打扰通知):
/**
* Subscribe to receive slice updates.
* @example
<pre>
let todos$ = slice.subscribe();
</pre>
*/
public subscribe(): Observable<E[]> {
this.notifyCount++;
return this.notify.asObservable();
}
在上面,我试图遵循推荐的最佳实践,即Observable
从ReplaySubject
.
这是对应的unsubscribe
方法:
/**
* Unsubscribe from slice updates.
*
* @example
<pre>
slice.unsubscribe(o);
</pre>
*/
public unsubscribe(o: ReplaySubject<E[]>) {
o.unsubscribe();
this.notifyCount--;
}
我必须将o
参数ReplaySubject
设为类型才能unsubscribe
. 但是,这与方法返回的Observable
类型相冲突。subscribe
尝试像这样进行测试时:
incompleteSlice.unsubscribe(incomplete$);
返回的消息是这样的:
[ts]“Observable”类型的参数不可分配给“ReplaySubject”类型的参数。“可观察”类型中缺少属性“调度程序”。让不完整的$:可观察的
关于如何解决这个问题的任何想法?
更新
刚刚想到的一个明显想法是,也许返回asObservable
意味着我们不再需要实际unsubscribe
从那个可观察到的。如果 Angular 组件被销毁,我们可以让它悬空吗?
解决方案
我认为您对退订Subscription
和退订感到困惑Subject
。
Angular 中实际推荐的是Subscription
在组件被销毁时取消订阅任何打开的内容。ASubscription
从 中返回Observable.subscribe
。当它被取消订阅时,它不再从源 observable 接收值,这在大多数情况下是你想要的。
取消订阅Subject
具有不同的效果。它将主题切换到closed
您无法再调用next
或订阅它的状态。您可以直接查看源代码以了解发生了什么。
取消订阅Observable
是不可能的,这就是您收到错误的部分原因。
为了遵循建议,您应该列出所有Subscriptions,即将每个 Subscription 添加到您以后可以访问的列表中,如下所示:
this.subscriptions$.push(obs$.subscribe...))
然后在组件销毁时,调用:
this.subscriptions$.forEach(sub -> sub.unsubscribe());
但在本文中由核心开发人员 Ben Lesh 推荐的更好的方法不是强制调用unsubscribe
,而是使用takeUntil
操作符。
StackOverflow 上有一个参考实现,用于将此模式与 Angular 一起使用,您可以将其用作起点。
推荐阅读
- python - 嵌套列表问题:更改列表采用的变量而不更改列表本身
- javascript - 在散列函数中使用 Javascript 中的浮点数
- jquery - 如何在 Jquery 中从 DOM 中删除元素
- angular - Google API 破坏了延迟加载模块中的更改检测器
- swift - Swift MPRemoteCommandCenter nextTrackCommand 被调用 3 次
- ftp - 使用 FTP 传输大型 SAS 数据集(~100 GB),如何验证没有遗漏数据?
- pdf-generation - R:在函数中创建 pdf 不起作用
- c++ - 使用前/后增量器分配容器迭代器
- excel - 在给定日期范围的情况下按季度设置开始和结束日期
- python - QAbstractItemModel 和 QModelIndex 之间的相互作用