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).
The general rule is for takeUntil to be placed last. However, there are some situations in which you might want want use it as the second-last operator. RxJS includes several operators that emit a value when the source observable to which they are applied completes.
The takeUntil operator returns an Observable that emits value from the source Observable until the notifier Observable emits a value. When the notifier emits a value, the TakeUntil completes the Source observable.
pipe(takeUntil(this. onDestroy$)) . subscribe((message: any) => { some code here; } takeUntil is a function in a component to unsubscribe when component is destroyed.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With