首页 > 解决方案 > 从 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$在每个组件中创建的引用也会悬空,直到组件本身被销毁。

背景

我正在尝试StoreAngular 的 API,并且我有一个重播主题,可以广播对商店切片的更改。这是允许订阅发生的方法(notifyCount 跟踪订阅,因此如果没有订阅,我们就不会打扰通知):

  /**
   * Subscribe to receive slice updates.
   * @example
     <pre>
    let todos$ = slice.subscribe();
    </pre>
  */
  public subscribe(): Observable<E[]> {
    this.notifyCount++;
    return this.notify.asObservable();
  }

在上面,我试图遵循推荐的最佳实践,即ObservableReplaySubject.

这是对应的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 组件被销毁,我们可以让它悬空吗?

标签: angulartypescriptrxjs

解决方案


我认为您对退订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 一起使用,您可以将其用作起点。


推荐阅读