typescript - RxJS 中点击运算符的输出问题
问题描述
我对以下代码的输出感到困惑,根据 take(3) 处理应该在渲染 10 后停止,但仍然从点击运算符获得 5,6 和 9。请参考下面的输出和代码片段。
- 抽头值空
- 挖掘值 20
- 渲染项目 20
- 挖掘值 15
- 渲染项目 15
- 挖掘值 10
- 渲染项目 10
- 完全的
- 挖掘值 5
- 挖掘值 6
- 挖掘值 9
of(null, 20, 15, 10, 5, 6, 9)
.pipe(
tap(val => console.log(`Tapped value ${val}`)),
filterNil(),
take(3)
)
.subscribe(
item => console.log(`Rendering Item ${item}`),
err => console.log(err),
() => console.log('Completed')
);
}
const filterNil = () => (source: Observable<any>) =>
new Observable(observer => {
return source.subscribe({
next(value) {
if (value !== undefined && value !== null) {
observer.next(value);
}
},
error(error) {
observer.error(error);
},
complete() {
observer.complete();
}
});
});
解决方案
这个问题的最终答案
以下帖子提供了此问题的正确答案。
我的第一个答案 - 一个简单的答案
您所看到的取决于您的代码是完全同步的事实,因此unsubscribe
隐含在 3 中的后 3 次发射take(3)
没有机会运行。
看看这个版本
of(null, 20, 15, 10, 5, 6, 9)
.pipe(
delay(0), // >>> intruduce a delay
tap(val => console.log(`Tapped value ${val}`)),
filterNil(),
take(3)
)
在这里,您介绍了 a delay
,它提供take
了可能性unsubscribe
,因此,您看到了您期望的行为。
不是答案,而是更详细的推理
我对这个问题进行了更多调查,并且发现了一些使我之前的答案过于简单的事情。
让我们从filterNil()
一个合法的自定义运算符开始,它应该与 执行相同的操作filter(item => item !== null)
,其中filter
一个运算符由 提供rxjs/operators
,即由库提供。
现在,如果我们替换filter(item => item !== null)
为filterNil()
,pipe
我们会得到不同的结果
of(null, 20, 15, 10, 5, 6, 9)
.pipe(
tap(val => console.log(`Tapped value ${val}`)),
filter(item => item !== null),
take(3)
)
.subscribe(
item => console.log(`Rendering Item ${item}`),
err => console.log(err),
() => console.log('Completed')
);
}
// the output on the console is
Tapped value null
Tapped value 20
Rendering Item 20
Tapped value 15
Rendering Item 15
Tapped value 10
Rendering Item 10
Completed
这意味着filter(item => item !== null)
和filterNil()
不等价。
它们不等价的事实似乎来自与和的某种不同性质的联合subscribe
方法的实现。Observable
filterNil
filter
使用时, Observable方法filterNil
的执行痕迹是这样的subscribe
另一方面,如果我们使用运算符,则Observable 方法
filter
的执行轨迹是这样的subscribe
因此,filterNil
确实将operator
属性设置为 null 而filter
确实将operator
属性设置为这一事实FilterOperator
似乎驱动了不同的行为。背后的原因我不清楚,值得提出一个新问题。
推荐阅读
- java - 使用 AgeFileFilter 读取特定日期文件
- android - 切换网页视图后的findElement不起作用
- javascript - 如何在通用 Windows 平台中检查互联网数据使用情况
- c - C中的格式调整
- android - React-Native Android 缺少选项卡屏幕
- javascript - 将第三方 API 集成到 WordPress 网站问题
- python - Python 输出重定向
- http - 我想将我的所有流量重定向到 http://www.mywebsite.com
- android - 在 Firestore 功能后设置适配器或 RecyclerView 刷新
- python-3.x - 跳过失败的软件包安装并使用 pip 安装替代方案