RxJs的操作符上篇

基本的几个操作符

  • of

    of操作的参数依次输出所有的数据,此时是同步的。

    let stream$ = Rx.Observable.of(1,2,3,4,5)
    
  • from

    from操作符的参数为数组。

    let stream$ = Rx.Observable.from([1,2,3,3,5])
    
  • do

    let stream$ = Rx.Observable.of(1,2,3,4).do(value => console.log(value))
    

    调试Observable使用

  • filter

    过滤操作

    let stream$ = Rx.Observable.of(1,2,3,4,5)
    .do(value => console.log(value))
    .filter((value) => value % 2 === 0);
    
    stream$.subscribe(value => console.log('value',value))
    

高阶Observable操作符

  • flatMap

对比理解 高阶函数 一个函数返回的还是一个函数。首先根据旧Observable的每个值重新产生一个新的Observable,然后flatMap重新将这些metastream的流中流变扁平

let stream$ = Rx.Observable.of(1,2,3)
.flatMap(val => {
    return Rx.Observable.of(val)
            .ajax({url: url})
            .map(e => e.response)
})
  • switchMap

    类似于 mergeMap,但是当源 Observable 发出值时会取消内部 Observable 先前的所有订阅 。

    在实际开发中,常用于级联调用。

    依赖调用意味这调用需要按照顺序执行,调用B必须再调用A执行返回后,

    开发场景:

    • 用户需要先登录
    • 然后获取用户详情
    • 然后可以获取用户订单
    let stream$ = Rx.Observable.of({message:'Login in'})
    .switchMap(result => {
      return Rx.Observable.of({id:1,name:'user'})
    }).switchMap(user => {
      return Rx.Observable.from([
        {id:114,userId:1},
        {id:117,userId:1}
      ])
    })
    
    stream$.subscribe(orders => console.log('Order',orders))
    

组合操作符

  • combineLatest

通常多个的Observable的组合在一起,我们通常需要使用组合操作符来组合两个或者两个以上的source

let source1 = Rx.Observable.interval(100).map(val => 'source1' + val).take(5);

let source2 = Rx.Observable.interval(50).map(val => 'source2' + val).take(2);

let stream$ = Rx.Observable.combineLatest(source1, source2);

stream$.subscribe(data => console.log(data));

业务场景

当你对每一个source的最新值都感兴趣的时候,而对之前的值不感兴趣的时候,可以选择使用使用combineLatest操作符来使用了。

  • concat

    按照顺序来发送Observable

    const getOne$ = Rx.Observable.timer(3000).mapTo({id:1});
    const getTwo$ = Rx.Observable.timer(1000).mapTo({id:2});
    
    Rx.Observable.concat(getOne$,getTwo$).subscribe(res => console.log(res));
    

    concat按照顺序来讲两个或者两个以上的Observable来组合起来,其中是严格的按照顺序来发送结果。

  • merge

    merge将所有的流都合并在一起, 要点是这个操作符组合了几个流,并且就像你在上面所看到的一样,任何像 delay() 这样的时间操作符都是起作用的。 而这个在concat上是不会起作用的。

    const getOne$ = Rx.Observable.of(1).delay(500);
    const getTwo$ = Rx.Observable.of(2,2,3,4,5);
    
    const merge$ = Rx.Observable.merge(getOne$,getTwo$).subscribe(value => console.log(value));
    
  • forkJoin

    Rxjs版本的Promise.all 方法,别让我知道直到所有的 Observables 都完成了,然后再一次性的给我所有的值。(以数组的形式)

    const getOne$ = Rx.Observable.timer(3000).mapTo({id:1});
    const getTwo$ = Rx.Observable.timer(1000).mapTo({id:2});
    
    Rx.Observable.forkJoin(getOne$,getTwo$).subscribe(results => console.log(results));
    
  • zip

    采用的是以列为基础连接值的方式来组合Observable, 如果最后一个参数是一个函数的话则将几个Observable的值都提取出来给函数传参来处理。 依次从每一个Source的相同位置获取值, 一般返回为数组。如果没法凑齐一组则抛弃其他的值。

    常规的用法

    const one$ = Rx.Observable.of(1,2,3);
    const two$ = Rx.Observable.of(4,5);
    const three$ = Rx.Observable.of(6,7);
    
    Rx.Observable.zip(one$,two$,three$).subscribe(value => console.log(value));
    

    zip带参数的使用方法

    const name$ = Rx.Observable.of('finch','wukong','zheng');
    const age$ = Rx.Observable.of(12,15,18);
    const address$ = Rx.Observable.of('shenzhen','wuhan','HK');
    
    Rx.Observable.zip(name$,age$,address$,(name,age,address) => ({name,age,address})).subscribe(value => console.log(value));
    

时间操作符

  • timer

    1. 参数为一个

      const getValue$ = Rx.Observable.timer(500);
      getValue$.subscribe(value => console.log(value));
      

      延迟发送一个数据,然后结束所有的数据。

    2. 参数为两个

      const getValue$ = Rx.Observable.timer(2000,100);
      getValue$.subscribe(value => console.log(value));
      // 首先延迟2S发送一个 然后每隔0.1S发送一个数据
      
  • Interval

    因为这个操作符会不停地生成值,所以倾向于和 take() 操作符一起使用,这样可以在调用它之前限制生成值的数量,就像这样:

    const getValue$ = Rx.Observable.interval(100).take(5)
    

    每隔0.1s发出一个值 然后获取其中的前五个

  • delay

    延迟发送Source每一个的数据。

    const getValue$ = Rx.Observable.interval(100).take(5);
    getValue$.delay(500).subscribe(value => console.log(value));
    
  • debounceTime

    Debounce 是一个已知的概念,特别是当你敲击键盘的时候。就像是在说,我们不在乎你的每次敲击键盘,但是一旦你停止打字后的一段时间是我们所关心的。

    业务场景

    在GUI编程中,比较常见的快速双击按钮是一个比较常见的功能需求,通常为了用户体验我们需要将过于快速的输入省略,直到用户停止输入然后我们才开始接下来的操作。

    const input = document.getElementById('input');
    
    const example = Rx.Observable
      .fromEvent(input, 'keyup')
      .map(i => i.currentTarget.value);
    
    // 在两次敲击键盘事件之间,有0.5秒的等待时间,如果时间小于0.5秒则丢弃前一个敲击键盘事件
    const debouncedInput = example.debounceTime(500);
    
    const subscribe = debouncedInput.subscribe(val => {
      console.log(`Debounced Input: ${val}`);
    });
    

    上面的代码只会输出一个值,值来源于 input 表单,在你停止打字后的500毫秒后,才值得它报告一下,也就是发出一个值。

你可能感兴趣的:(RxJs的操作符上篇)