rxjs Observable filter Operator 的实现原理介绍

Jerry Wang 发表于 2022/12/02 10:26:04 2022/12/02
【摘要】 本文分享笔者在实际 Angular 项目开发过程中,使用 rxjs filter 操作符的一些经验。

本文分享笔者在实际 Angular 项目开发过程中,使用 rxjs filter 操作符的一些经验。

看下面这段使用 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.

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。