如果您基本上有相同的问题,并且上下文是Angular,则可能需要阅读答案中的所有注释以获取更多上下文。
进行let observe$ = someReplaySubject.asObservable()
时,是否不再需要取消订阅observe$
?换句话说,我们可以从多个Angular组件实例中调用let observe$ = someReplaySubject.asObservable()
,而不必担心从notify
实例到相应的Observable
的连接吗?
如果我们有一个ReplaySubject<Todo[]>
实例(我们叫它rxTodo
,我们可以通过以下方式从Angular组件中订阅它:
let todoObs$:Observable<Todo[]> = rxTodo$.asObservable()
,那么即使该组件被破坏,在每个组件中创建的todoObs$
引用也将悬而未决,直到组件本身被破坏。
我正在尝试针对Angular的Store
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] 无法将类型“可观察”的参数分配给类型“ ReplaySubject”的参数。 类型“可观察”中缺少属性“调度程序”。 让incomplete $:可观察
关于如何解决此问题的任何想法?
我想到的一个显而易见的想法是,也许返回asObservable
意味着我们不再需要实际上从该可观察值中unsubscribe
。如果Angular组件被破坏,我们可以悬空吗?
答案 0 :(得分:2)
我认为您对退订Subscription
和Subject
感到困惑。
当组件被销毁时,Angular中实际建议的是取消订阅任何打开的Subscription
。 Subscription
返回了Observable.subscribe
。取消订阅后,它不再从可观察的来源接收值,这是大多数情况下想要的。
退订Subject
会有不同的效果。它将主题切换到closed
状态,在此状态下您将无法再调用next
或订阅它。您可以look directly at the source code来了解发生了什么。
无法退订Observable
,这部分是您收到错误的原因。
为了遵循建议,您应该列出所有订阅,即将每个订阅添加到稍后可以访问的列表中,如下所示:
this.subscriptions$.push(obs$.subscribe...))
然后在销毁组件时,调用:
this.subscriptions$.forEach(sub -> sub.unsubscribe());
但更好的是,recommended by Core Developer Ben Lesh in this article不是强制调用unsubscribe
,而是利用takeUntil
运算符。
There is a reference implementation on StackOverflow用于将此模式与Angular一起使用,您可以将其用作起点。