Reputation: 387
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.
Upvotes: 13
Views: 6686
Reputation: 449
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.
Upvotes: 10
Reputation: 21638
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))
)
Upvotes: 5