响应式编程是一种面向数据流和变更传播的异步编程范式(Wikipedia)。RxJS(响应式扩展的 JavaScript 版)是一个使用可观察对象进行响应式编程的库,它让组合异步代码和基于回调的代码变得更简单 (RxJS Docs)。
RxJS 提供了一种对 Observable
类型的实现,直到 Observable
成为了 JavaScript 语言的一部分并且浏览器支持它之前,它都是必要的。这个库还提供了一些工具函数,用于创建和使用可观察对象。这些工具函数可用于:
- 把现有的异步代码转换成可观察对象
- 迭代流中的各个值
- 把这些值映射成其它类型
- 对流进行过滤
- 组合多个流
让我接受的最基本的用法解释:
RxJS中的流以Observable对象呈现,获取数据需要订阅Observable,形式如下:
const ob = http$.getSomeList(); //getSomeList()返回某个由‘Observable’包装后的http请求。
ob.subscribe((data) => console.log(data)); //使用内部定义的subscribe方法来订阅数据,然后打印出该数据。
//在变量末尾加$表示Observable类型的对象
而与ECMAScript6中的promise方法类似:
const promise = http.getSomeLIst(); //返回由‘promise’包装的http请求。
promise.then((data) => console.log(data)); //then是promise内部定义的方法
而实际上Observable
可以认为是加强版的Promise
,它们之间是可以通过RxJS
的API
互相转换的:
const ob = Observable.fromPromise(somePromise); //Promise转为Observable
const promise = someObservable.toPromise(); //Observable转为Promise
能让我理解的知识才是最好的知识:
Observable
被称为可观察序列,简单来说数据就在Observable
中流动,你可以使用各种operator
对流进行处理,例如:
const ob = Observable.interval(1000);
ob.take(3).map(n => n*2).filter(n => n>0).subscribe(n => console.log(n));
第一步代码我们通过类方法interval
创建了一个Observable
序列,ob
作为源会每隔1000ms
发射一个递增的数据,即0 -> 1 -> 2
。第二步我们使用操作符对流进行处理,take(3)
表示只取源发射的前3
个数据,取完第三个后关闭源的发射;map
表示将流中的数据进行映射处理,这里我们将数据翻倍;filter
表示过滤掉出符合条件的数据,根据上一步map
的结果,只有第二和第三个数据会留下来。
上面我们已经使用同步编程创建好了一个流的处理过程,但此时ob
作为源并不会立刻发射数据,如果我们在map
中打印n
是不会得到任何输出的,因为ob
作为Observable
序列必须被“订阅”才能够触发上述过程,也就是subscribe
(发布/订阅模式)。
上面代码中我们给subscribe
传入了一个函数,这其实是一种简写,subscribe
完整的函数签名如下,包含三个自定义函数next、error和complate:
ob.subscribe({ next: d => console.log(d), error: err => console.error(err), complete: () => console.log('end of the stream') })
直接给subscribe
传入一个函数会被当做是next
函数。这个完整的包含3个函数的对象被称为observer
(观察者),表示的是对序列结果的处理方式。next
表示数据正常流动,没有出现异常;error
表示流中出错,可能是运行出错,http
报错等等;complete
表示流结束,不再发射新的数据。在一个流的生命周期中,error
和complete
只会触发其中一个,可以有多个next
(表示多次发射数据),直到complete
或者error
。
observer.next
可以认为是Promise
中then
的第一个参数,observer.error
对应第二个参数或者Promise
的catch
。
RxJS
同样提供了catch
操作符,err
流入catch
后,catch
必须返回一个新的Observable
。被catch
后的错误流将不会进入observer
的error
函数,除非其返回的新observable
出错。