当前位置:网站首页>rxjs Observable filter Operator 的实现原理介绍
rxjs Observable filter Operator 的实现原理介绍
2022-07-03 12:34:00 【汪子熙】
看下面这段使用 filter Operator 的代码:
import {
fromEvent, interval, MonoTypeOperatorFunction } from 'rxjs';
import {
filter } from 'rxjs/operators';
function filterKey(key) {
console.log('input: ', key);
const result: MonoTypeOperatorFunction<KeyboardEvent> = filter(
(event: KeyboardEvent) => {
console.log('input event: ', event);
return event.key === key;
}
);
console.log('result: ', result);
return result;
}
fromEvent(document, 'keyup')
.pipe(filterKey('Enter'))
.subscribe(
(data) => console.log(data) // KeyboardEvent
);
原始 Observable 调用 pipe,执行自定义 Operator 的逻辑,在逻辑里生成一个 filter Operator 实例。单步调试如下:

返回一个 filterOperatorFunction:

filter 调用返回的是一个 filterOperatorFunction:
至此我们只完成了 pipe 两段调用的第一段:得到 filter 返回的 filterOperatorFunction.

然后执行 pipe 操作的第二段,如上图图例所示,将原始 Observable 传入 filterOperatorFunction:

这个第二段操作,就会创建新的 FilterOperator 实例,在 lift 操作里,新建一个 Observable,然后把原始的 Observable 设置为这个新 Observable 实例的 source 字段,将 FilterOperator 实例赋给原始 Observable 的 Operator 字段。
pipe 调用执行的结果,返回一个新的 Observable 给 pipe 的调用者。最后我们 subscribe 的,就是这个 pipe 返回的 Observable.

subscribe 内部,this 就是 pipe 返回的新 Observable,operator 指向 filterOperator,source 指向 fromEvent 返回的原始 Observable:

首先利用 TypeScript 对象结构语法,object destructing,将 this.operator 字段赋给变量 Operator,然后以原始 Observable 作为上下文,调用 filter Operator.
这样,pipe 返回的 Observable 上进行订阅,会传递到原始 Observable 的 subscribe 操作:
当我们在键盘上随便敲击一个字符后,触发 MouseEvent 对应的 handler,在 handler 里调用 Observer 的 next 操作。

next 操作最后会触发 filtersubscriber predicate 属性即应用开发人员传入 filter Operator 的匿名函数:

filter 输入参数也是一个函数,该函数的输入即 MouseEvent:
fromEvent 新建的 Observable,其实现逻辑内部,同样调用了 subscriber 的 next 方法来发射值。同时 fromEvent 返回的 Observable 同其他创建操作符比如 of 的特色之处,就在于其能够响应各种事件,比如 document 的 keyup 事件。

这种事件注册机制,是在上图 setupSubscription 函数里实现的。
注册的具体实现,采取了浏览器原生提供的 addEventListener,调用者为 document 全局对象,传入的 eventName 为 keyup,handler 即 fromEvent 内部实现,即上图绿色高亮区域内的代码。
export declare function filter<T>(predicate: (value: T, index: number) => boolean, thisArg?: any): MonoTypeOperatorFunction<T>;

filter Operator 接受一个 predicate 作为输入参数,返回一个类型为 MonoTypeOperatorFunction 的函数。
这里的 T 为类型参数。MonoType 对应 T,意思是单参数。
MonoTypeOperatorFunction 是一种特殊的 OperatorFunction,当后者的输入和返回参数都相同时,即特殊化为单类型 OperatorFunction:
OperatorFunction 又是一种特殊的 UnaryFunction(一元函数),当一元函数的输入和输出类型都是一个 Observable 时,即特殊化成了 OperatorFunction.

边栏推荐
- R语言使用data函数获取当前R环境可用的示例数据集:获取datasets包中的所有示例数据集、获取所有包的数据集、获取特定包的数据集
- Grid connection - Analysis of low voltage ride through and island coexistence
- STM32 and motor development (from MCU to architecture design)
- Oracle memory management
- Loan calculator my pressure is high
- Four problems and isolation level of MySQL concurrency
- R语言gt包和gtExtras包优雅地、漂亮地显示表格数据:nflreadr包以及gtExtras包的gt_plt_winloss函数可视化多个分组的输赢值以及内联图(inline plot)
- Kotlin - 改良装饰者模式
- Cache penetration and bloom filter
- 剑指 Offer 15. 二进制中1的个数
猜你喜欢

2022-02-14 incluxdb cluster write data writetoshard parsing

2022-02-09 survey of incluxdb cluster
![[Database Principle and Application Tutorial (4th Edition | wechat Edition) Chen Zhibo] [Chapter 6 exercises]](/img/c0/92e9e52f1f643b66720697523a1794.png)
[Database Principle and Application Tutorial (4th Edition | wechat Edition) Chen Zhibo] [Chapter 6 exercises]

106. 如何提高 SAP UI5 应用路由 url 的可读性
![[data mining review questions]](/img/96/00f866135e06c4cc0d765c6e499b29.png)
[data mining review questions]

解决 System has not been booted with systemd as init system (PID 1). Can‘t operate.

已解决(机器学习中查看数据信息报错)AttributeError: target_names

Seven habits of highly effective people

今日睡眠质量记录77分

STM32 and motor development (from MCU to architecture design)
随机推荐
Differences and connections between final and static
Flink SQL knows why (19): the transformation between table and datastream (with source code)
[Database Principle and Application Tutorial (4th Edition | wechat Edition) Chen Zhibo] [Chapter III exercises]
C graphical tutorial (Fourth Edition)_ Chapter 17 generic: genericsamplep315
已解决TypeError: Argument ‘parser‘ has incorrect type (expected lxml.etree._BaseParser, got type)
Two solutions of leetcode101 symmetric binary tree (recursion and iteration)
mysqlbetween实现选取介于两个值之间的数据范围
SLF4J 日志门面
Will Huawei be the next one to fall
In the promotion season, how to reduce the preparation time of defense materials by 50% and adjust the mentality (personal experience summary)
Tencent cloud tdsql database delivery and operation and maintenance Junior Engineer - some questions of Tencent cloud cloudlite certification (TCA) examination
STM32 and motor development (from MCU to architecture design)
[Exercice 5] [principe de la base de données]
【数据库原理及应用教程(第4版|微课版)陈志泊】【第五章习题】
Harmonic current detection based on synchronous coordinate transformation
Cadre de logback
开始报名丨CCF C³[email protected]奇安信:透视俄乌网络战 —— 网络空间基础设施面临的安全对抗与制裁博弈...
显卡缺货终于到头了:4000多块可得3070Ti,比原价便宜2000块拿下3090Ti
【数据库原理及应用教程(第4版|微课版)陈志泊】【第七章习题】
The foreground uses RSA asymmetric security to encrypt user information