避免在 Angular 2+ 中嵌套订阅?

Car*_*tti 6 rxjs angular

我有两个端点:

  • 1 个端点来获取当前用户的登录信息。
  • 1 个端点来获得此用户的授权。

其实我用:

this.user
  .subscribe((e) => {
     this.grants.get(e)
        .subscribe((x) => {
            console.log(x)
         })
  })
Run Code Online (Sandbox Code Playgroud)

但这是 Angular 2+/RxJS 的反模式。

我想知道如何按照 Angular/RxJS 最佳实践执行此操作。

谢谢

Mic*_*l D 6

避免嵌套订阅取决于可观察对象的性质以及它们如何相互依赖:

相互依赖的可观察量

当观察到的(this.grants.get())依赖于从另一个观察到的(通知this.user),你可以使用任何RxJS的高阶绘图运营商switchMapmergeMapconcatMapexhaustMap。每个人都有自己的目的。您可以在此处找到它们之间的差异。

与他们相关的简短差异

  • switchMap - 如果外部 observable 发出,则取消内部 observable
  • mergeMap - 为每个外部通知触发内部 observable(扁平化外部通知)
  • concatMap- 基本上mergeMap在任何时候都有单个并发请求(扁平化外部通知但按顺序发出它们)
  • exhaustMap - 如果内部 observable 尚未完成,则忽略外部通知

使用switchMap运算符的插图

this.user.pipe(
  switchMap(e => this.grants.get(e))
).subscribe((x) => {
  console.log(x)
});
Run Code Online (Sandbox Code Playgroud)

独立观察

如果 observables 彼此独立,您可以使用 RxJS 函数,如forkJoin,combineLatestzip并行触发 observables。

与他们相关的简短差异

  • forkJoin? - 仅在所有 observable 完成时发出
  • combineLatest?,?- 当任何observables 发出时发出(没有排放的 observables 将发出旧值)
  • zip?,?- 当所有observables 发出时发出

插图使用 forkJoin

forkJoin(this.obs1, this.obs2, ...).subscribe(
  res => console.log(res)
);
Run Code Online (Sandbox Code Playgroud)

? - 从每个 observable 发出一组通知(例如,(this.obs1, this.obs2, ...)将发出['res from obs1', 'res from obs2', ...])。

? - 所有 observable都应该至少发射一次,以便操作员发射