I am having trouble understanding the finalize operator in RxJS. Let me demonstrate this on an example:
of(null).pipe(
tap({ complete: () => console.log('tap 1 completes') }),
finalize(() => console.log('finalize')),
tap({ complete: () => console.log('tap 2 completes') })
).subscribe({ complete: () => console.log('subscribe completes') });
I would expect the finalize
callback to be executed before the second tap
. That's not happening, though. Rather the above code produces the following output:
tap 1 completes
tap 2 completes
subscribe completes
finalize
Looking at the implementation I believe the operator is passed (lifted) through the whole observable chain to always be applied at its end. So now I end up with two questions:
tap
in the above example) rather than at the end of the observable chain?It's important to be aware that finalize()
and tap()
work very differently. tap()
is triggered by next
, error
and complete
notifications while finalize()
is only triggerd on chain ubsubscription. In other words finalize()
is very similar to using:
const subscription = $source.subscribe();
// This will be always triggered after all `tap()`s
subscription.add(() => console.log('same as finalize()'));
So you can't make finalize()
to be invoked before tap()
. Also, be aware that finalize()
is invoked also when you manually unsubscribe liek the following:
subscription.unsubscribe(); // will always invoke `finalize()` but never `tap()`
One possible solution could be implementing you own finalize()
variant that knows the reason why it's being called: https://github.com/martinsik/rxjs-extra/blob/master/doc/finalizeWithReason.md (see source code)
Also note, that https://github.com/ReactiveX/rxjs/pull/5433 will have no affect on your use-case.
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