为什么在 RxJS 中取消了 finalize? [英] Why is finalize lifted in RxJS?

查看:97
本文介绍了为什么在 RxJS 中取消了 finalize?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解 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:

  1. 这个设计决定背后的基本原理是什么?你能解释一下为什么这是一个理想的/有利的财产吗?
  2. 是否有不同的运算符或其他解决方案来在完成和出错时执行代码,但是按顺序(即在上面的示例中的第二个 tap 之前)而不是在可观察链的末端?
  1. What's the rationale behind this design decision? Can you give some explanation on why this is a desireable / advantageous property?
  2. 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()nexterrorcomplete 通知触发,而 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆