angular - 尽管在异步管道订阅的管道中,Observable 似乎仍然存在

标签 angular rxjs

在我们的应用程序中,我们有一个页面,只有在设置了特定状态时才应导航到该页面,我们在 Page C 上将其称为 requiredState$

用户必须在前往所述页面的途中选择一些值,这样他就可以在Page B 上设置requiredState$。用户可以多次启动此选择循环,这意味着他将多次导航到 Page C。起点是页面A。从页面 A 导航到页面 B 后,状态会重置。

顺序是页面A(重置状态)->页面B(选择状态)->页面C(需要状态)->页面A等。

为了避免在未设置 requiredState$ 的情况下导航到 Page C,我们在 Page C 的管道中进行了以下检查:

this.intermediateObservable$ = this.requiredState$.pipe(
  tap((requiredState) => {
    if (!requiredState) {
      // navigate back to Page B (*)
      this.cancelPipe$.next();
    }
  }),
  // ...
  takeUntil(this.cancelPipe$),
  // ...
);

cancelPipe$ 是一个简单的 Subject

Observable this.intermediateObservable$ 用在三个地方

  1. 产生显示的数据

    this.data$ = this.intermediateObservable$.pipe(...)

    然后由 HTML 模板中的 async 管道订阅

  2. 当用户选择一个类别时

    this.intermediateObservable$.pipe(
      take(1)
    ).subscribe((someData) => {
      // filter out desired category and save to state service
    });
  1. 当用户想要显示信息数据时
    this.modalContent$ = this.intermediateObservable$.pipe(
      // map information to show
    );

同样,this.modalContent$ 通过 async 管道传递给模态

问题

第一个周期,一切正常。用户在 Page B 上设置状态,导航到 Page C 做更多的事情,然后返回到 Page A。现在,如果他开始第二个周期,他将导航到 Page B(就在导航之前,重置所需状态)。这似乎触发了来自 Page C 的标记行 (*),导致“双重导航”到 Page B

这怎么可能?我知道 pipe() 创建了一个新的可观察对象,这意味着它们共有三个。

  1. 和 3. 不是直接订阅的,而是后来通过 async 管道订阅的,应该自动处理。
  2. 使用了take(1)操作符,据我理解应该是之后直接退订。

最佳答案

答案很简单:在成功的情况下我们没有调用 this.cancelPipe$.next(),这意味着 takeUntil() 没有被调用并且管道仍然活跃。

关于angular - 尽管在异步管道订阅的管道中,Observable 似乎仍然存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64642175/

相关文章:

javascript - 如何从组件更改服务变量的值?

javascript - 如何在悬停父级上打开子div?

Angular - 如何发出具有多个订阅者/主题的 HTTP 请求

reactive-programming - 将 Rx Observable 拆分为多个流并单独处理

Angular2 正在向控制台记录错误,即使我在 RXJS observable 中捕获/吃掉错误

javascript - 将 angularjs 服务注入(inject) Angular

angular - 在ngrx中订阅store时如何访问之前的状态和当前状态并进行比较?

angular - Jasmine 单元测试 - 无法读取未定义的属性管道

javascript - RXJS 在 html5 Canvas 上画线

angular - RxJS 6 页面不活动时暂停或缓冲可观察