I think there’s one key misunderstanding:
You either have someone who wants “success and finally”, or “success and error” but none wants the 3 of them.
This isn’t entirely true. Each Observable can send zero or more next
notifications and one error
or complete
notification but never both. For example when making a successful HTTP call you’ll have one next
and one complete
notification. On error HTTP request you’ll have only one error
notification and that’s all. See http://reactivex.io/documentation/contract.html
This means you’ll never have an Observable emitting both error
and complete
.
And then there’s the finalize
operator. This operator is invoked when disposing the chain (which includes plain unsubscribing as well). In other words it’s called after both error
and complete
notifications.
So the second example you have is correct. I understand it looks weird that you include finalize
before subscribing but in fact each emissions from the source Observable goes first from top to bottom where it reaches subscribers and there if its error
or complete
notification it triggers dispose handlers bottom up (in opposite order) and at this point finalize
is called. See https://github.com/ReactiveX/rxjs/blob/master/src/internal/Subscriber.ts#L150-L152
In your example using finalize
is the same as adding the dispose handler yourself into a Subscription
objects.
const subscription = this.service.getAll()
.subscribe(
(data) => this.onSuccess(data),
(error) => this.handleError(error)
);
subscription.add(() => this.stopLoading());