陌小路的个人博客 陌小路的个人博客
首页
  • 技术专区

    • 面试
    • Vue
    • Electron
    • TypeScript
    • Serverless
    • GraphQL
  • 我的秋招之旅
  • 2019年终总结
Todo
收藏夹
关于作者
GitHub

陌小路

前端切图仔
首页
  • 技术专区

    • 面试
    • Vue
    • Electron
    • TypeScript
    • Serverless
    • GraphQL
  • 我的秋招之旅
  • 2019年终总结
Todo
收藏夹
关于作者
GitHub
  • Vue

  • React

  • 面试

  • Electron

  • Serverless

  • GraphQL

  • TypeScript

  • RxJS

    • 介绍
    • 前置知识点
    • Observable
    • Observer
    • Subscription与Subject
    • Cold-Observables与Hot-Observables
    • Schedulers
    • Operators概念
      • 创建型Operators
      • 转换操作符
      • 过滤操作符
      • 组合操作符
      • 总结
    • 工程化

    • Webpack

    • Nestjs

    • WebRTC & P2P

    • Docker

    • Linux

    • Git

    • Svelte

    • 踩坑日记 & 小Tips

    • 其他

    • technology
    • RxJS
    陌小路
    2020-12-22

    Operators

    # Operator概念

    采用函数式编程风格的纯函数 (pure function),使用像 map、filter、concat、flatMap 等这样的操作符来处理集合。也正因为他的纯函数定义,所以我们可以知道调用任意的操作符时都不会改变已存在的Observable实例,而是会在原有的基础上返回一个新的Observable。

    尽管 RxJS 的根基是 Observable,但最有用的还是它的操作符。操作符是允许复杂的异步代码以声明式的方式进行轻松组合的基础代码单元。

    Observable图

    # 实现一个Operator

    假设我们不使用RxJS提供的过滤操作符,那么让你自己实现又该怎么做呢?

    function filter(source, callback) {
        return Rx.Observable.create(((observer) => {
            source.subscribe(
                (v) => callback(v) && observer.next(v),
                (err) => observer.error(err),
                (complete) => observer.complete(complete)
            );
        }))
    }
    const source = Rx.Observable.interval(1000).take(3);
    filter(source, (value) => value < 2).subscribe((value) => console.log(value));
    
    // 0
    // 1
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    这样就实现了一个简单的filter操作符,是不是很简洁,其实主要的做法还是像上面所说,基于传入的Observable,返回一个新的Observable。

    代码中首先创建了一个Observable,接着用一个新的观察者订阅传入的源,并调用回调函数判断是否这个值需要继续下发,如果为false,则直接跳过,根据我们传入的源与过滤函数来看,源对象最终会发送三个数0、1、2,打印结果为0、1,2被过滤了。

    当然我们也可以将其放置到Rx.Observable.prototype上以便以我们可以采用this的方式获取源:

    Rx.Observable.prototype.filter = function (callback) {
        return Rx.Observable.create(((observer) => {
            this.subscribe(
                (v) => callback(v) && observer.next(v),
                (err) => observer.error(err),
                (complete) => observer.complete(complete)
            );
        }))
    }
    Rx.Observable.interval(1000).take(3).filter((value) => value < 2).subscribe((value) => console.log(value));
    
    // 0
    // 1
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    这样是不会就更加简洁了,就像我们使用原生数组的filter方法一样。

    要说这两种方式的区别,其实也比较好理解,一个是放在prototype中,能够被实例化的对象直接调用,另一个是定义了一个新的函数,可以用来导出给调用者使用(其实也可以直接挂载到Observable的静态属性上)。

    看到这里估计会有读者已经猜到笔者接下来说讲解什么了。

    # 实例操作符-静态操作符

    • 实例操作符:通常是能被实例化的对象直接调用的操作符。我们一般更多会使用实例操作符多一点,比如filter、map、concat等等。使用实例操作符可以更快乐的使用this,而省去一个参数,还能维持链式调用。
    • 静态操作符:Observable是一个class类,我们可以直接把操作符挂载到他的静态属性上,好处在于无需实例化即可调用,缺点在于就无法再使用this的方式进行目标对象调用了,而是需要把目标对象传入。

    如果添加一个实例化属性上面已经有示例了,这里就不做过多赘述了。

    将上述的filter例子改造一下,将其挂载到静态属性上:

    Rx.Observable.filter = (source, callback) => {
        return Rx.Observable.create(((observer) => {
            source.subscribe(
                (v) => callback(v) && observer.next(v),
                (err) => observer.error(err),
                (complete) => observer.complete(complete)
            );
        }))
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    编辑
    上次更新: 2023/11/25, 4:11:00
    Schedulers
    创建型Operators

    ← Schedulers 创建型Operators→

    最近更新
    01
    github加速
    01-01
    02
    在线小工具
    01-01
    03
    Lora-Embeddings
    11-27
    更多文章>
    Theme by Vdoing | Copyright © 2020-2024 STDSuperman | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式