• RXJS 系列 04


    每日前提

    1. 内容为学习后的自我总结。再次感谢博主的分享,附上原po链接: 原po链接

    十分枯燥的各种 API 操作符

    1. operator:

      • distinct 去重

      • distinctUntilChanged

        • 最常见的状况是我们在做多方同步时。当我们有多个Client,且每个Client 有着各自的状态,Server 会再一个Client 需要变动时通知所有Client 更新,但可能某些Client 接收到新的状态其实跟上一次收到的是相同的,这时我们就可用distinctUntilChanged 方法只处理跟最后一次不相同的讯息
        • 说人话:如果最新推送的状态跟最后一次状态相同,则此次状态不必推送,保留最后一次状态即可
      • catch

        • 如果回传当前observable,造成的效果就是无限循环,可以用在断线重连的场景

          var source = Rx.Observable.from(['a','b','c','d',2])
                      .zip(Rx.Observable.interval(500), (x,y) => x);
          
          var example = source
                          .map(x => x.toUpperCase())
                          .catch((error, obs) => obs); // 将当前的ob回传
          
          example.subscribe({
              next: (value) => { console.log(value); },
              error: (err) => { console.log('Error: ' + err); },
              complete: () => { console.log('complete'); }
          }); 
          
          source : ----a----b----c----d----2|
                  map(x => x.toUpperCase())
                   ----a----b----c----d----X|
                  catch((error, obs) => obs)
          example: ----a----b----c----d--------a----b----c----d--..
          
      • retry(number:Number)

        • number:尝试几次
        • 即时同步的重新连接,在连线断掉后,不断的尝试
      • retryWhen 作用:错误通知或是例外收集

      • repeat 作用:建立轮询

    2. 处理二维observable的operator: Observable<Observable<T>> => Observable<T>

      • concatAll() 多个obs 按顺序执行,如果其中有个是无限的,那么下一次永不会执行

        var click = Rx.Observable.fromEvent(document.body, 'click');
        var source = click.map(e => Rx.Observable.interval(1000).take(3)); // 每次输出3个数,执行完了,才会执行下个observable
        var source = click.map(e => Rx.Observable.interval(1000)); // 一直执行,第二个ob 永不会执行 
        
        var example = source.concatAll();
        example.subscribe({
            next: (value) => { console.log(value); },
            error: (err) => { console.log('Error: ' + err); },
            complete: () => { console.log('complete'); }
        });
        
        click  : ---------c-c------------------c--.. 
                map(e => Rx.Observable.interval(1000))
        source : ---------o-o------------------o--..
                                              
                             ----0----1----2|   ----0----1----2|   take(3)
                             ----0----1----2|
                             concatAll()
        example: ----------------0----1----2----0----1----2--..
        
      • switch 切换。字面意思,只要目标条件出现,就切换到下一个observableobservable

        • 在新的observable送出后直接处理新的observable不管前一个observable是否完成,每当有新的observable送出就会直接把旧的observable退订(unsubscribe),永远只处理最新的observable
        var click = Rx.Observable.fromEvent(document.body, 'click');
        var source = click.map(e => Rx.Observable.interval(1000));
        
        var example = source.switch();
        example.subscribe({
            next: (value) => { console.log(value); },
            error: (err) => { console.log('Error: ' + err); },
            complete: () => { console.log('complete'); }
        });
        
        click  : ---------c-c------------------c--.. 
                map(e => Rx.Observable.interval(1000))
        source : ---------o-o------------------o--..
                                              ----0----1--...
                             ----0----1----2----3----4--...
                             ----0----1----2----3----4--...
                             switch()
        example: -----------------0----1----2--------0----1--...
        
      • mergeAll(number: Number)

        • merge 他可以让多个observable 同时送出元素,mergeAll 也是同样的道理,它会把二维的observable 转成一维的,并且能够同时处理所有的observable
        • number: 同时处理的observable 数量
        var click = Rx.Observable.fromEvent(document.body, 'click');
        var source = click.map(e => Rx.Observable.interval(1000));
        
        var example = source.mergeAll();
        example.subscribe({
            next: (value) => { console.log(value); },
            error: (err) => { console.log('Error: ' + err); },
            complete: () => { console.log('complete'); }
        });
        
        click  : ---------c-c------------------c--.. 
                map(e => Rx.Observable.interval(1000))
        source : ---------o-o------------------o--..
                                              ----0----1--...
                             ----0----1----2----3----4--...
                             ----0----1----2----3----4--...
                             switch()
        example: ----------------00---11---22---33---(04)4--...
        
        从Marble Diagram 可以看出来,所有的observable 是并行(Parallel)处理的,也就是说mergeAll 不会像switch 一样退订(unsubscribe)原先的observable 而是并行处理多个observable。以我们的范例来说,当我们点击越多下,最后送出的频率就会越快。
        
        
        var click = Rx.Observable.fromEvent(document.body, 'click');
        var source = click.map(e => Rx.Observable.interval(1000).take(3));
        
        var example = source.mergeAll(2);  //并行处理 2 个 observable
        example.subscribe({
            next: (value) => { console.log(value); },
            error: (err) => { console.log('Error: ' + err); },
            complete: () => { console.log('complete'); }
        });
        
        click  : ---------c-c----------o----------.. 
                map(e => Rx.Observable.interval(1000))
        source : ---------o-o----------c----------..
                                      ----0----1----2|     
                             ----0----1----2|  
                             ----0----1----2|
                             mergeAll(2)
        example: ----------------00---11---22---0----1----2--..
        
        当mergeAll 传入参数后,就会等处理中的其中一个observable 完成,再去处理下一个。以我们的例子来说,前面两个observabel 可以被并行处理,但第三个observable 必须等到第一个observable 结束后,才会开始。
        
        concatAll 就是 mergeAll(1) 的特殊情况
        
    3. xxxAll + Map

    • concatMap(ob, { e, res, outObIndex, inObIndex}) 作用: 确保每一个request 会等前一个request 完成才做处理。 比如: 某些操蛋的大文件上传,必须要等上一个分片传输完毕才继续上传下一个
      • 参数解析: concatMap 还有第二个参数是一个selector callback,这个callback 会传入四个参数:
        • 外部 observable 送出的元素
        • 内部observable 送出的元素
        • 外部 observable 送出元素的 index
        • 内部observable 送出元素的index
    • switchMap:switch + map
    • mergeMap(func, {}, number): number控制并行数量。 merge + map
    • 总结:
      • concatMap用在可以确定内部的observable结束时间比外部observable发送时间来快的情境,并且不希望有任何并行处理行为,适合少数要一次一次完成到底的的UI动画或特别的HTTP request行为。
      • switchMap 用在只要最后一次行为的结果,适合绝大多数的使用情境。
      • mergeMap 用在并行处理多个observable,适合需要并行处理的行为,像是多个I/O 的并行处理。
    1. 实践: 自动填充 附上仓库链接
  • 相关阅读:
    HTTP状态码
    python 连接 MySQL 数据库
    JS事件基础和绑定
    7月13号:2D的转换和过渡,动画效果设置
    JS事件流
    7月14日:JS的基础语法
    JS对表单的操作
    7月16日:DOM总结
    DOM样式表
    7月9号
  • 原文地址:https://www.cnblogs.com/xyJen/p/12869706.html
Copyright © 2020-2023  润新知