Reputation: 54741
Is the operator takeUntil affected by other operators, and do you have to use it twice inside a switchMap?
For example;
Assume that I have an observable that emits a value when I no longer want to subscribe, and we'll refer to this as this._destroyed
.
Does it matter if there is a delay operator before a takeUntil?
of("something").pipe(
delay(1000),
takeUntil(this._destroyed)
);
Is the above any different from reversing the order?
of("something").pipe(
takeUntil(this._destroyed),
delay(1000)
);
What if I use switchMap
do I have to call takeUntil
twice?
of("something").pipe(
takeUntil(this._destroyed),
delay(1000),
switchMap(() => {
return of("other").pipe(
takeUntil(this._destroyed),
delay(1000)
);
}
);
Is the above functionally the same as calling takeUntil
once?
of("something").pipe(
delay(1000),
switchMap(() => {
return of("other").pipe(delay(1000));
}),
takeUntil(this._destroyed)
);
I guess I'm confused as to what happens when takeUntil
is triggered and stops the current subscription. How is it impacted by when it is called in the pipe order (if there is any impact at all).
Upvotes: 18
Views: 10333
Reputation: 2008
My understanding is that generally takeUntil
should be the last operator in a chain because it can result in leaks. This article describes the issue: https://ncjamieson.com/avoiding-takeuntil-leaks/
The article uses the following example:
import { combineLatest, Observable } from "rxjs";
import { takeUntil } from "rxjs/operators";
declare const a: Observable<number>;
declare const b: Observable<number>;
declare const notifier: Observable<any>;
const c = a.pipe(
takeUntil(notifier),
o => combineLatest(o, b)
).subscribe(value => console.log(value));
From the article:
When the notifier emits, the observable returned by the takeUntil operator completes, automatically unsubscribing any subscribers.
However, the subscriber to c is not subscribed to the observable returned by takeUntil — it’s subscribed to the observable returned by combineLatest — so it’s not automatically unsubscribed upon the takeUntil observable’s completion.
The subscriber to c will remain subscribed until all of the observables passed to combinedLast complete. So, unless b completed before the notifier emitted, the subscription to b would leak.
While this post specifically refers to switchMap
, I suspect the logic is the same. It may be less of an issue with switchMap
, as there is only one inner observable.
Upvotes: 16