When speaking about Observables (especially rxjs), what is the difference between "finally" and "done" or "complete"?
An observable can either produce values (calling the next callback), or it can complete, calling either the complete or error callback.
A well-behaved Observable will call an Observer's complete() method exactly once or the Observer's error(err) method exactly once, as the last notification delivered.
In these cases, the observable will call . complete() after it has emitted all of it's values. There's no need to unsubscribe. It completes on it's own, which means it unsubscribes all subscribers automatically.
The biggest difference is that Promises won't change their value once they have been fulfilled. They can only emit (reject, resolve) a single value. On the other hand, observables can emit multiple results. The subscriber will be receiving results until the observer is completed or unsubscribed from.
Finally always happens whenever an observable sequence terminates (including errors); completed only happens when it terminates without errors.
Finally:
Invokes a specified action after the source observable sequence terminates gracefully or exceptionally.
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/finally.md
OnCompleted:
An Observable calls this method after it has called
onNext
for the final time, if it has not encountered any errors.
http://reactivex.io/documentation/observable.html
"Done" isn't an rx/observables concept. I've just seen it printed in examples of "Complete" / "OnComplete".
Note: when you call subscribe
, the syntax is usually:
observable.subscribe([observer] | [onNext], [onError], [onCompleted]);
// Like this:
observable.subscribe(
(value) => { ... },
(error) => { ... },
() => { console.log('complete!'); }
);
or
observable.subscribe({
next: x => console.log('got value ' + x),
error: err => console.error('something wrong occurred: ' + err),
complete: () => console.log('done'),
});
Whereas finally
is handled like this:
observable.finally(() => { console.log('finally!'); })
.subscribe(...) // you can still call subscribe
To be more precise, the finally()
operator adds a dispose handler. The complete
notification just calls the complete handler in observers.
What this means in practise:
When using finally()
the callback is going to be called in every situation that causes unsubscription. That's when complete
and error
notifications are received by observers but also when you manually unsubscribe.
See demo: https://jsbin.com/dasexol/edit?js,console
complete
or error
handlers are called only when the appropriate notification is received. Only 0 - 1
handlers can be called but never both of them.
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