Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why nested subscription is not good?

Tags:

angular

rxjs

I know that nested subscriptions should be avoided and rxjs operators should be used, but the articles I found about this issue usually just saying that nested subscriptions is bad without explaining why(besides saying 'may cause issues') .

I'm wondering if anyone can help on this one? Thank you.

like image 344
dmd Avatar asked Nov 11 '19 07:11

dmd


2 Answers

Good that you are asking since this is a common problem.

Consider something like

service.cal1().subscribe(val => {
  service.call2(val).subscribe( res => {
    *does things*
  }
}

What you are triggering is a new Subscription (and therefor a new executed pipe) for each an every value that get emited by the Observable of call1(). This can leave you with hundreds of unhandled Observables ans Subscriptions which all stay in memory for the time being.

You need to know that when you subscribe() to a Observable multiple times, your subscribers won't listen to the exact same source, instead they all trigger a new copy of your defined Observable pipeline.

As stated in the first example in the Observable Docu

Observable that pushes the values 1, 2, 3 immediately (synchronously) when subscribed

Emphasize mine

The Observable does nothing on its own but starts its whole journey whenever subscribed

That is why you would try to use something like switchMap() to change to the other call instead of leaving the original subscription as is.

like image 191
Chund Avatar answered Sep 21 '22 02:09

Chund


let sub1, sub2, sub3, sub4;
sub1 = service.call1().subscribe(result1 => {
  sub2 = service.call2(result1).subscribe(result2 => {
    sub3 = service.call3(result2).subscribe(result3 => {
      sub4 = service.call4(result3).subscribe(result4 => {
        // Do stuff with result 4
      });
    });
  });
});

vs

let sub = service.call1().pipe(
  switchMap(result1 => service.call2(result1)),
  switchMap(result2 => service.call3(result2)),
  switchMap(result3 => service.call4(result3)),
  switchMap(result4 => service.call5(result4))
)
like image 45
Adrian Brand Avatar answered Sep 23 '22 02:09

Adrian Brand