美文网首页
07RxJS过滤类操作符

07RxJS过滤类操作符

作者: learninginto | 来源:发表于2021-01-07 10:01 被阅读0次
    audit(节流)

    频繁地触发某一事件,设置其在规定的时间内只触发一次,达到节流的效果(用于搜索框中请求数据等)

    在定时器发出值之前,会忽略所有源Observalbe发出的值,直到定时器发出值,会推送源Observalbe最近发出的一次值

    const clicks = fromEvent(document, 'click').pipe(pluck('clientX'))
    const result = clicks.pipe(audit(ev => interval(2000)))
    result.subscribe(x => console.log(x))
    

    如果在2秒内频繁地触发click事件,audit只会把最近的一次发送出来。

    auditTime

    类似audit,如果只用到定时的作用,auditTime更方便。重写上面的例子:

    const clicks = fromEvent(document, 'click').pipe(pluck('clientX'))
    const result = clicks.pipe(auditTime(2000))
    result.subscribe(x => console.log(x))
    
    throttle(节流)

    不同于audit的是,throttle有第二个参数,接收一个配置项,控制节流函数的触发时期

    const interval$ = interval(100)
    const result = interval$.pipe(throttle(ev => interval(2000)))
    result.subscribe(x => console.log(x))
    
    * 配置项
    ```js
    const defaultThrottleConfig:ThrottleConfig = {
        leading:true, //节流开始前调用,默认为true
        trailing:false //节流开始后调用,默认为false
    }
    
    • 使用配置项
    const interval$ = interval(100)
    const result = interval$.pipe(throttle(ev => interval(2000), { leading: false, trailing: true }))
    result.subscribe(x => console.log(x))
    //20
    //40
    //60
    //……
    
    throttleTime

    类似throttle

    const interval$ = interval(500)
    const result = interval$.pipe(throttleTime(2000))
    result.subscribe(x => console.log(x))
    //0
    //21
    //42
    //……
    
    debounce(防抖)

    当源Observable持续发送流,直到间隔的时间大于给定的时间,才执行最后一次(用于监听滚动条事件等)

    与audit的区别:

    1. audit是否发出值取决于timer是否发出值
    2. debounce是否发出值取决源Observable的发射间隔是否大于给定的timer
    const clicks = fromEvent(document, 'click')
    const result = clicks.pipe(debounce(() => interval(1000)))
    result.subscribe(x => console.log(x))
    
    debounceTime

    类似debounce,重写上面的例子:

    const clicks = fromEvent(document, 'click')
    const result = clicks.pipe(debounceTime(2000))
    result.subscribe(x => console.log(x))
    
    distinct(去重)

    依次发出源Observable的值,只是每次只发出与之前不同的值(或者之前从没出现过的值)

    of(1, 1, 2, 2, 2, 3, 4).pipe(distinct()).subscribe(x => console.log(x))
    //1 2 3 4
    

    还可以指定过滤函数

    interface Person{
        age:number,
        name:string
    }
    of<Person>(
      { age: 4, name: 'Foo' },
      { age: 7, name: 'Bar' },
      { age: 5, name: 'Foo' }
    ).pipe(
      distinct((p: Person) => p.name),
    ).subscribe(x => console.log(x))
    //{age: 4, name: "Foo"}
    //{age: 7, name: "Bar"}
    
    distinctUntilChanged

    当源Observable发出了与上一次不同的值时,才把当前值推送出去

    of(1, 1, 2, 2, 1, 1, 2, 3).pipe(distinctUntilChanged())
    .subscribe(x => console.log(x))
    //1 2 1 2 3
    

    还可以指定过滤函数

    interface Person {
      age: number,
      name: string
    }
    of<Person>(
      { age: 4, name: 'Foo' },
      { age: 7, name: 'Bar' },
      { age: 5, name: 'Foo' }
    ).pipe(
      distinctUntilChanged((p: Person, q: Person) => p.name === q.name),
    ).subscribe(x => console.log(x))
    //{age: 4, name: "Foo"}
    //{age: 7, name: "Bar"}
    //{age: 5, name: "Foo"}
    
    distinctUntilKeyChanged

    当源Observable发出的值,它的key与上一次的key不同时,才把当前值推送出去(与上面的操作效果一样,只不过是换了一个操作符)

    of<Person>(
      { age: 4, name: 'Foo' },
      { age: 7, name: 'Bar' },
      { age: 5, name: 'Foo' }
    ).pipe(
      distinctUntilKeyChanged('name'),
    ).subscribe(x => console.log(x))
    

    更精细的匹配

    of<Person>(
      { age: 4, name: 'Foo' },
      { age: 7, name: 'Bar' },
      { age: 5, name: 'Foo' }
    ).pipe(
      distinctUntilKeyChanged('name', (x: string, y: string) => x.substring(0, 3) === y.substring(0, 3)),
    ).subscribe(x => console.log(x))
    //{age: 4, name: "Foo"}
    //{age: 7, name: "Bar"}
    //{age: 5, name: "Foo"}
    

    比较的只是{ag,所以全部打印

    elementAt

    发出指定索引的那个值

    const clicks = fromEvent(document, 'click')
    const result = clicks.pipe(elementAt(2));
    result.subscribe(x => console.log(x))
    

    这里可能会点击很多次,但只会触发第二次的click事件

    ignoreElements

    忽略源Observable发出的所有值,除了complete和error

    of('you', 'talking', 'to', 'me').pipe(ignoreElements())
      .subscribe(
        word => console.log(word),
        err => console.log('error', err),
        () => console.log('the end')
      )
    //the end
    
    filter

    类似数组的filter

    const clicks = fromEvent(document, 'click')
    const clicksOnDivs = clicks.pipe(filter(ev => (ev.target as HTMLElement).tagName === 'DIV'))
    clicksOnDivs.subscribe(x => console.log(x))
    
    first

    只取第一个发出的值,与first对应的操作符是last.

    const clicks = fromEvent(document, 'click')
    const clicksOnDivs = clicks.pipe(first())
    clicksOnDivs.subscribe(x => console.log(x))
    

    也可以指定第一个值符合的条件

    const clicks = fromEvent(document, 'click')
    const clickOnDivs = clicks.pipe(first(ev => (ev.target as HTMLElement).tagName === 'DIV'))
    clicksOnDirs.subscribe(x => console.log(x))
    
    last
    of('one', 'two', 'three').pipe(last()).subscribe(res => console.log(res))
    //three
    
    sample

    忽略源Observable发出的值,直到另一个Observable发出值,才推送源Observable最近发出的值

    const seconds = interval(1000)
    const clicks = fromEvent(document, 'click')
    const result = seconds.pipe(sample(clicks))
    result.subscribe(x => console.log(x))
    

    定时器持续在计算,但未触发,直到click才推送流

    sampleTime

    每隔指定的时间发出最近的一个值

    const seconds = interval(1000)
    const result = seconds.pipe(sampleTime(3000))
    result.subscribe(x => console.log(x))
    //1
    //4
    //7
    
    single

    类似first,发出第一个值,但如果源Observalbe有多个值,就会直接进入error

    //从1开始,同时发起5个数字
    const numbers = range(1, 5).pipe(single())
    numbers.subscribe(x => console.log(x), e => console.log('error'))
    //error
    

    也可以指定过滤函数

    const numbers = range(1, 5).pipe(single(item => item === 3))
    numbers.subscribe(
      x => console.log('get result', x),
      e => console.log('error'))
    //get result 3
    

    筛选出的结果必须只有一个符合的值,否则也是直接进入error

    const numbers = range(1, 5).pipe(single(item => item > 3))
    numbers.subscribe(
      x => console.log('get result', x),
      e => console.log('error'))
    //error
    
    skip

    跳过前面的n个值开发推送数据

    const source = interval(1000)
    const example = source.pipe(skip(3));
    const subscribe = example.subscribe(val => console.log(val))
    //3 
    //4 
    //5
    
    skipLast

    忽略最后的n个值

    const many = range(1, 5)
    const skipLastTwo = many.pipe(skipLast(2))
    skipLastTwo.subscribe(x => console.log(x))
    

    从1开始,发送5个值,通过pipe忽略最后的2个值,所以打印1,2,3

    skipUntil

    一直忽略源Observable发出的值,直到另一个Observable发出值为止

    const intervalObservalbe = interval(1000)
    const click = fromEvent(document, 'click')
    const emitAfterClick = intervalObservalbe.pipe(skipUntil(click))
    const subscribe = emitAfterClick.subscribe(value => console.log(value))
    

    第一个Observalue虽然一直在计时,但它会等到当第二个Observalbe发出值的时候才推送出来,并且一直执行下去,打印的时间以第二个Observalbe推送的时间为准。

    skipWhile

    忽略所有符合条件的值

    const source = interval(1000);
    const example = source.pipe(skipWhile(val => val < 5))
    const subscribe = example.subscribe(val => console.log(val))
    //6 7 8 9 10 ……
    
    take

    只取前n个值

    const intervalCount = interval(1000);
    const takeFive = intervalCount.pipe(take(1))
    takeFive.subscribe(x => console.log(x))
    //1
    //2
    //3
    
    takeLast

    只取最后n个值

    const intervalCount = range(1, 100)
    const takeFive = intervalCount.pipe(takeLast(3))
    takeFive.subscribe(x => console.log(x))
    //98
    //99
    //100
    
    takeUntil

    不断推送源Observable发出的值,直到另一个Observalbe发出值为止

    const source = interval(1000)
    const clicks = fromEvent(document, 'click')
    const result = source.pipe(takeUntil(clicks))
    result.subscribe(x => console.log(x))
    
    takeWhile

    只取符合条件的值

    const source = range(1, 8)
    const example = source.pipe(takeWhile(val => val <= 4))
    const subscribe = example.subscribe(val => console.log(val))
    //1
    //2
    //3
    //4
    

    相关文章

      网友评论

          本文标题:07RxJS过滤类操作符

          本文链接:https://www.haomeiwen.com/subject/thoaoktx.html