[RxJs(转)] No.4 RxJS系列教程(四) Observable(转)

转自(感谢):
RxJS系列教程(四) Observable

我们知道Observable是个容器,里面包含着数据,数据从何而来?

静态数据

我们日常重度使用的stringarray都属于此范畴。

动态数据

比如我们用ES6中的generator生成斐波那契数列,比如通过RESTful api调用返回的数据。

Observables发送事件,Observer异步地接收事件,这可以让我们的应用在有大量事件产生的时候保持响应能力。强调一下,RxJS不是仅面向客户端js的,在服务端同样可以使用。看下代码:

Rx.Observable.from(<数据源>)
  .operator1(...)
  .operator2(...)
  .operator3(...)
  .subscribe(<处理最终结果数据>)

再强调两个事情,第一,observables是个不可变数据类型,像string一样;第二,observables不仅仅代表了当前时刻的数据,也代表了未来某时刻的数据。

何时何地用RxJS

世间没有万能药,RxJS也一样,只在适合它的地方使用它。我们把程序按照两个维度划分成一个田字表格,横向是单值,多值,纵向是同步,异步。

单值,同步

用Rx.Observable.of来包装单值同步数据:

Rx.Observable.of(2017)

一旦有消费者消费,此值马上被发送出去。这种情况下使用RxJS显得有点重了,除非我们想进行合并流的操作。

多值,同步

用Rx.Observable.from来包装多值同步数据:

Rx.Observable.from([1, 2, 3])

from()函数可能是RxJS中最常用的之一了。同步在这里是啥意思呢?就是说1处理完了才能处理2,2处理完了才能处理3。如果1处理得慢,2必须等着,以此类推。

单值,异步

这个情况其实就是Promise。RxJS提供了函数可以无缝地和Promise整合到一起。

const one = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 3000);//模拟3秒延迟
});
//这个时候Promise中的代码已经在运行了

Rx.Observable.fromPromise(one)
  .map(value => value = value + 1);
  .subscribe(result => {
    console.log(result);
  });

console.log("程序结束");

由于是异步程序,一运行就会打印“程序结束”,3秒后将打印2。然而用Observable包装一层有啥意义?意义在于Promise是无法重新运行的,而Observable可以,并且还可以让它运行很多次,这是通过内嵌Observable来实现的,我们后面会讲到。

多值,异步

这个场景就是我们常说的事件驱动的异步编程。比如DOM事件以及NodeJS中的EventEmitter。如何使用RxJS包装DOM事件,如下图:

[RxJs(转)] No.4 RxJS系列教程(四) Observable(转)_第1张图片
包装DOM事件

这里我用的是https://jsfiddle.net/。点击span标签,在控制台打印出span标签中的href属性值。

EventEmitter的包装在这里我们就暂时不讲了,以后碰上再说。感兴趣的可以看下RxJS的文档。

拉模型与推模型

迭代器就是基于拉的获取数据的代表。最有代表性的示例就是利用ES6中的Generator来生成斐波那契数列。Generator的教程请参见http://es6.ruanyifeng.com/#docs/generator。基于拉的获取数据的方式就是我想要数据的时候才去获取数据,是主动的去获取数据。

而Observable是基于推的获取数据方式的。数据会主动推送给我,我被动地接收数据做出响应。

以上说了那么多,想表明一件事就是,RxJS可以用同样的方式来处理同步和异步编程,并且把如何产生数据和如何消费数据各自独立出来。

我们可以把一切东西都转换成Observable,但是应该不应该就要视情况而定了。比如转换字符串大小写,直接用string的方法就可以了。RxJS中的任何操作都会有性能损失。

你可能感兴趣的:([RxJs(转)] No.4 RxJS系列教程(四) Observable(转))