I wonder, if there is any difference in performance between using .take(1)
and .unsubscribe
when unsubscribe
is used right after the subscription:
var observable = Rx.Observable.interval(100);
First:
var subscription = observable.subscribe(function(value) { console.log(value); }).unsubscribe();
Second:
var subscription = observable.take(1).subscribe(function(value) { console.log(value); });
Any ideas of it makes any different regard the performance?
You should always unsubscribe when using the events observables from the Router in components (there is one exception tough, namely if you use it in the root component) as the subscription is still alive, even if the component was destroyed by Angular.
The RxJS first() operator waits until the first value is emitted from an observable and then automatically unsubscribes, so there is no need to explicitly unsubscribe from the subscription.
These are called “finite subscriptions”. If you subscribe with a “take(1)”, as another example, it is finite and doesn't need to be unsubscribed. This is easy enough to test out if you are unsure of it being finite or infinite. For example, you could console.
The best place to make the notifier to emit so the observable$ is canceled is in the ngOnDestroy hook.
Each serves a different purpose so it's hard to compare them.
In general if you take this source:
const source = range(1,3);
... and consume it with subscribe()
followed immediately by unsubscribe()
:
source.subscribe( console.log, undefined, () => console.log('complete') ).unsubscribe();
... then all values from source
are going to be emitted even though we called unsubscribe()
right after subscribing. This is because the code is still strictly sequential (synchronous) and the source
is a cold Observable.
1 2 3 complete
Btw, try adding delay(0)
operator to make source.pipe(delay(0)).subscribe(...).unsubscribe()
. This makes emitting values asynchronous using an actual setTimeout()
call and for this reason unsubscribe()
is called before any next
handlers and is discarded immediately.
In other words unsubscribe()
let's you stop receiving values anytime. Even when the source hasn't emitted any value (we never receive any complete notification).
Using take()
operator limits the chain to only emit a specific number of values.
source.pipe( take(1), ) .subscribe( console.log, undefined, () => console.log('complete') );
This just emits a single value and completes:
1 complete
Even if you add .unsubscribe()
the result would be the same.
See live demo: https://stackblitz.com/edit/rxjs-tbu5kb
So take()
is an operator while unsubscribe()
is a method on a Subscription
object. These two things are often interchangeable but they never fully substitute each other.
Jan 2019: Updated for RxJS 6
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