【问题标题】:understand the behavior of nested observables理解嵌套的 observables 的行为
【发布时间】:2019-08-02 17:01:57
【问题描述】:

我正在开发一个 Angular 7 应用程序,我知道嵌套订阅函数是一种反模式,但是在管道函数中正确使用转换运算符(如 mergeMap、switchMap ...)我总是可以避免它。 我正面临着一种我无法理解内部可观察对象如何工作的情况。我有一种过滤器,它在一个可观察的事件发出信号后完全初始化,在这个事件之后,我必须通过 formGroup 上的 .valueChanges 监听表单更改,格式化过滤器并最终过滤结果。

this.filters.categoriesReady.asObservable()
      .pipe(
        tap((categories) => {
          this._createControlsCategories(categories);
          this.categories = categories;
          console.log('higher order observable');
        }),
        switchMap(() => this.filterForm.valueChanges),
        switchMap(filtersRaw => this._formatFilters(filtersRaw)),
        takeUntil(this.unsubscribe)
      )
      .subscribe(
        filtersFormatted => {
          this.filterResults(filterFormatted);
          this.filterUpdated.emit(true);
        }
      );

我认为内部流this.filterForm.valueChanges 不起作用,因为它依赖于事件this.filters.categoriesReady,它只被触发一次(实际上是console.log 打印一次),所以我认为它并不总是听我喜欢的。相反,每次对过滤器应用更改时,都会执行订阅函数中的代码。 谁能给我解释一下?

【问题讨论】:

  • 通过 switchMap 你实际上订阅了 observable 并且每次都会通知你。它不会在第一次发出后取消订阅。如果您只想从特定的 observable 中获取最新值,请尝试使用 withLatestFrom
  • 我建议阅读 switchMap 文档,因为它可能没有按照您的意愿执行。
  • switchMap 是这样工作的:假设你只对最新的 JS 趋势感兴趣。每次一个新的 JS 框架问世,你都想忘记所有以前的框架,成为最新流行框架的专家。因此,您订阅了“新的 JS 框架已发布”可观察到,以便在新框架发布时收到通知。而且每次出去,你都会退订关于旧框架的博客,然后订阅关于最新框架的博客。因此,在您的情况下,每次 categoriesReady 发出时,您都会订阅表单发出的所有更改。

标签: angular observable


【解决方案1】:

switchMap 在外部 observable 发射后切换到一个新的内部 observable,因此外部只需要发射一次。但是,switchMap 的行为是,每次外部可观察对象发出时,它都会取消并重新订阅内部可观察对象。

TBH,在这种情况下,您似乎只是在使用外部 observable 来保证内部 observable 在 categoriesReady observable 发出之前不会被订阅。我不确定这背后的原因是什么,当您不能仅仅独立订阅两者时,因为它们似乎并不相互依赖......,我也不知道为什么_formatFilters 返回一个可观察的。

但希望能清除 switchMap 的行为

【讨论】:

  • 你明白了,bryan,我使用外部 observable 来通知类别已成功从远程获取,并能够创建和注册反应式表单控件。我可以独立订阅this.filterForm.valueChanges 并且仍然可以工作,但我想防止在注册类别控件时发出 valueChanges。
  • 我可能会使用 combineLatest 或 withLatestFrom 来完成此任务并仍然保持单独的流
  • 好的,我会尝试一下,我明白你说我“switchMap 在外部可观察对象发射后切换到新的内部可观察对象,因此外部只需要发射一次”但最后一个switchMap 不是.valueChanges 而是this._formatFilters(filtersRaw) 的流,因此我不认为.valueChanges 仍在“听”。提前谢谢,我希望我自己解释一下
  • 所有内部 observables 仍在监听。他们只是在发出新值后取消并重新订阅
猜你喜欢
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 2019-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多