Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

rxjs - Avoiding nesting subscriptions in Angular 2+?

I have 2 endpoints:

  • 1 endpoint to get current user logged.
  • 1 endpoint to get grants of this user.

Actually I use:

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

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

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

Thanks

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

Co-dependent observables

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.

Brief differences b/n them

  • 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

Illustration using switchMap operator

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

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.

Brief differences b/n them

  • 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

Illustration using forkJoin

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

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

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...