避免在 Angular 2+ 中嵌套订阅? [英] Avoiding nesting subscriptions in Angular 2+?

查看:20
本文介绍了避免在 Angular 2+ 中嵌套订阅?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 2 个端点:

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

实际上我使用:

this.user
  .subscribe((e) => {
     this.grants.get(e)
        .subscribe((x) => {
            console.log(x)
         })
  })

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

But this is an anti-pattern of Angular 2+/RxJS.

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

I would like to know how to do this following Angular/RxJS best practices.

谢谢

推荐答案

避免嵌套订阅取决于 observable 的性质以及它们如何相互依赖:

Avoiding nested subscriptions depends on the nature of the observables and how they depend on each other:

当一个 observable (this.grants.get()) 依赖于另一个 observable (this.user) 的通知时,你可以使用任何更高的 RxJS顺序映射操作符switchMapmergeMapconcatMapexhaustMap.每个人都有自己的目的.您可以在此处找到它们之间的差异.

When an observable (this.grants.get()) depends on the notification from another observable (this.user), you could use any of the RxJS higher order mapping operators switchMap, mergeMap, concatMap and exhaustMap. Each has their own purpose. You could find the differences between them here.

b/n 的简要差异

  • switchMap - 如果外部可观察对象发出,则取消内部可观察对象
  • mergeMap - 为每个外部通知触发内部 observable(扁平化外部通知)
  • concatMap - 本质上是 mergeMap 随时具有单个并发请求(扁平化外部通知但按顺序发出它们)
  • exhaustMap - 如果内部 observable 尚未完成,则忽略外部通知
  • switchMap - cancel inner observable if the outer observable emits
  • mergeMap - trigger inner observable for each outer notification (flatten the outer notifications)
  • concatMap - essentially mergeMap with single concurrent request at any time (flattens the outer notifications but emit them in order)
  • exhaustMap - ignore outer notifications if inner observable hasn't completed

使用switchMap操作符的说明

this.user.pipe(
  switchMap(e => this.grants.get(e))
).subscribe((x) => {
  console.log(x)
});

独立的可观察对象

如果 observables 相互独立,你可以使用 RxJS 函数如 forkJoincombineLatestzip 来并行触发 observables.

Independent observables

If the observables are independent of each other, you could use RxJS functions like forkJoin, combineLatest or zip to trigger the observables in parallel.

B/n 的简要区别

  • forkJoinα - 仅当所有 observables 完成时才发出
  • combineLatestα,β - 当任何 observables 发射时发射(没有发射的 observables 将发射旧值)
  • zipα,β - 当所有 observables 发出
  • forkJoinα - emit only when all the observables complete
  • combineLatestα,β - emit when any of the observables emit (observables w/o emissions will emit old value)
  • zipα,β - emit when all of the observables emit

使用forkJoin

forkJoin(this.obs1, this.obs2, ...).subscribe(
  res => console.log(res)
);

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

α - emits an array of notifications from each observable (eg. (this.obs1, this.obs2, ...) will emit ['res from obs1', 'res from obs2', ...]).

β - 所有 observables应该 至少发射一次以供操作员发射

β - all observables should emit atleast once for the operator to emit

这篇关于避免在 Angular 2+ 中嵌套订阅?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆