RxJS学习笔记(1)

作者: 谦啸 | 来源:发表于2018-01-02 23:43 被阅读278次

    RxJS

    概述

    RxJS全名Reactive Extensions for JavaScript,起源于Reactive Extensions项目,该项目主要实现各种语言的响应式编程(Reactive programming)库,被认为是观察者模式与函数式编程相结合的最佳实践。官方是这样吹嘘的:

    Reactive Revolution:ReactiveX is more than an API, it's an idea and a breakthrough in programming. It has inspired several other APIs, frameworks, and even programming languages.

    而RxJS是其项目中一个基于JavaScript的库,主要用于解决js中的异步编程问题。说到这里,我们又不得不提一下响应式编程的思想,其主要思路如下:

    响应式的思路:是把随时间不断变化的数据、状态、事件等等转成可被观察的序列(Observable Sequence),然后订阅序列中那些Observable对象的变化,一旦变化,就会执行事先安排好的各种转换和操作。

    RxJS是比ES7中async/await更高层面的流程逻辑抽象,把异步带来的时间因素给剥离到了程序流程外部,描述了一个动态的数据结构(数据流,stream)。因为我们平时写代码时都是关注程序执行的瞬间,即静止状态,缺少了时间这个维度。所以RxJS就给我们提供了很多与时间无关的通用高层抽象,即数据流操作算符api。通过这些api,我们可以自由地定义数据流的过滤、转换和组合等操作的组合关系,而无需关心具体操作的实现。

    好处

    1. 事件产生逻辑与处理逻辑分离

    2. 事件处理逻辑被数据结构化,能自由组合,方便修改扩展(函数式编程的思想)

    Why RxJS

    RxJS是最近几年兴起的,关注度还是挺高的(github上有18000+star)。但是其理念还是比较抽象的,所以学习成本还是有点大的。

    那么为什么还是要学呢?

    因为最近项目框架转型,由angularjs转向angular2+,这次Google和微软联手,angular和typescript打包,也就顺带引入了小弟RxJS(捂脸)。

    不过,引入RxJS也存在着一个问题,就像知乎上说的:

    Rx 的一个问题就是它其实是一个 paradigm,侵入性很强。你如果要用 Rx 写东西,最好就整个系统都是以 Rx 为核心来设计。

    如何过渡到RxJS

    这里主要以angularjs过渡到angular中使用RxJS为例。

    普通的Promise

    对于一个普通的promise,我们一般处理如下:

    promise().then(
      ()=>{
        // success
      },
      ()=>{
        // error
      });
    

    而在RxJS中,我们一般得到的是一个Observable(可观察对象),类似的像上面一样的处理被称为订阅,其实现如下:

    observable().subscribe(
      ()=>{
        // next
      },
      ()=>{
        // error
      },
      ()=>{
        // complete
      });
    

    这里的next就相当于success,但又不同。因为Observable(可观察对象)是基于推送(Push)运行时执行(lazy)的多值集合,所以对一个Observable的订阅可能产生多个next。不过对于一般的http请求,只会产生一个next。不过,两者的error基本相同。但是,这里需要注意的是,complete只会在next执行完成后调用,error时不调用。大致逻辑如下:

    const observable = Observable.create(function (observer) {
          try {
            observer.next(1);
            observer.next(2);
            observer.next(3);
            observer.complete();
          } catch (err) {
            observer.throw(new Error(err));
          }
        });
    

    并发promise

    在应用场景中,我们可能需要同时发送多个请求,并且成功后才进行处理。

    Promise中提供了all()方法,接收参数为一个可迭代对象,使用如下:

    const promise = Promise.all([promiseA, promiseB, promiseC]);
    promise().then(
      ()=>{
        // success
      },
      ()=>{
        // error
      });
    

    类似的,angularjs中提供了$q.all()。

    而在RxJS中,也提供了相应的操作算符api,即Observable.forkJoin(),用法与上面类似:

    const observable = Observable.forkJoin(observableA, observableB, observableC);
    observable().subscribe(
      ()=>{
        // next
      },
      ()=>{
        // error
      });
    

    需要注意的是,RxJS5以后,这种算符的使用都需要加上相应的引用,如这里需要加上import 'rxjs/add/observable/forkJoin'

    串行promise

    考虑另一种场景,请求B调用依赖请求A成功后返回的数据。

    在Promise中我们通常如下处理:

    promiseA.then(
      data=>{
        // promiseA success
        return promiseB(data);
      },
      ()=>{
        // error
      }).then(
        ()=>{
          // promiseB success
        },
        ()=>{
          // error
        });
    

    类似的,RxJS中也提供了相应的api,即Observable.mergeMap(),用法如下:

    observableA.mergeMap(
      data=>{
        // observableA next
        return observableB(data);
      }).subscribe(
        data=>{
          // observableB next
        },
        ()=>{
          // error
        });
    

    改造promise

    为了方便向使用RxJS库的过渡,RxJS中还提供了toPromise()、fromPromise()方法,方便进行Observable对象与Promise对象之间的相互转换。

    To be continue

    当然RxJS的功能还远不止这些,持续更新中...如果有什么问题,欢迎小伙伴们一起讨论,大家一起共同进步=。=

    相关文章

      网友评论

        本文标题:RxJS学习笔记(1)

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