为什么在 RxJS 中取消了 finalize? [英] Why is finalize lifted in RxJS?
问题描述
我无法理解 RxJS 中的 finalize 运算符.让我用一个例子来证明这一点:
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') });
我希望在第二个 tap
之前执行 finalize
回调.然而,这并没有发生.而是上面的代码产生以下输出:
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
之前)而不是在可观察链的末端?
- What's the rationale behind this design decision? Can you give some explanation on why this is a desireable / advantageous property?
- Is there a different operator or other solution to execute code on complete and on error, but in order (i.e. before the second
tap
in the above example) rather than at the end of the observable chain?
推荐答案
请务必注意 finalize()
和 tap()
的工作方式非常不同.tap()
由 next
、error
和 complete
通知触发,而 finalize()
> 仅在链订阅时触发.换句话说,finalize()
与 using 非常相似:
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()'));
所以你不能让 finalize()
在 tap()
之前被调用.另外,请注意 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()`
一种可能的解决方案可能是实现您自己的 finalize()
变体,它知道被调用的原因:https://github.com/martinsik/rxjs-extra/blob/master/doc/finalizeWithReason.md (见源代码)
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)
另请注意,https://github.com/ReactiveX/rxjs/pull/5433 不会影响您的用例.
Also note, that https://github.com/ReactiveX/rxjs/pull/5433 will have no affect on your use-case.
这篇关于为什么在 RxJS 中取消了 finalize?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!