rxjs - 为什么在 RxJS 中解除了 finalize?
问题描述
我无法理解RxJS 中的finalize运算符。让我用一个例子来证明这一点:
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') });
我希望finalize
回调在第二个之前执行tap
。不过,这并没有发生。而是上面的代码产生以下输出:
tap 1 completes
tap 2 completes
subscribe completes
finalize
查看实现,我相信操作员通过整个可观察链传递(提升)以始终在其末端应用。所以现在我有两个问题:
- 这个设计决策背后的基本原理是什么?你能解释一下为什么这是一个理想/有利的属性吗?
- 是否有不同的运算符或其他解决方案可以在完整和错误时执行代码,但按顺序(即在
tap
上面示例中的第二个之前)而不是在可观察链的末尾?
解决方案
重要的是要意识到这一点finalize()
并以tap()
非常不同的方式工作。tap()
由 触发next
,通知 whileerror
仅在链订阅时触发。换句话说,与使用非常相似:complete
finalize()
finalize()
const subscription = $source.subscribe();
// This will be always triggered after all `tap()`s
subscription.add(() => console.log('same as finalize()'));
所以你不能finalize()
在之前被调用tap()
。另外,请注意,finalize()
当您手动取消订阅时也会调用以下内容:
subscription.unsubscribe(); // will always invoke `finalize()` but never `tap()`
一种可能的解决方案可能是实现您自己的finalize()
变体,该变体知道它被调用的原因:https ://github.com/martinsik/rxjs-extra/blob/master/doc/finalizeWithReason.md (参见源代码)
另请注意,https://github.com/ReactiveX/rxjs/pull/5433不会影响您的用例。
推荐阅读
- github - 当我是存储库中唯一的贡献者/维护者时,为什么 github 会提出“比较和拉取请求”?
- vb.net - VB.net Serial.write 在 Windows 7 上很慢
- php - php call php file as image outside public directory
- c++ - 如何设置矩阵的值与 mex 和 openmp 并行?
- android - 在 Kotlin 的 ImageView 上显示图像
- git - 如何完全阻止/限制推送到远程主机
- c# - SMTP 服务器响应为 5.7.1 客户端未通过身份验证
- django - 为什么较低的内置过滤器在 Django 模板 2.2 中不起作用?
- asynchronous - gRPC 是否支持 ASYNCHRONOUS SERVER 以及通过服务器端类似回调机制的异步客户端?
- node.js - 从 id 数组中获取 firestore 文档列表