1、简介
RxJS 全名是Reactive Extension for JavaScript,即JavaScript 的响应式扩展。
响应式的思路是把随时间不断变化的数据、状态、事件等转成可被观察的序列(Observe Sequence),然后订阅序列中那些 Observable 对象的变化,一旦变化,
就会执行事先安排好的各种转换和操作。RxJS作为一个库,可以和任何框架混用。
2、data stream
以一个click event 来说,在用户点击的动作发生后,会有一段时间出发了几个事件:value, error or completed signal, 如下图:
RxJS 将任何事情包括variables, user inputs, properties, caches, data structures等都转化为data streams,并通过observe 这些 data streams的变化,做出响应的处理。
3、RxJS 安装 http://reactivex.io/rxjs/manual/installation.html
4、创建 Observable
Observable(可观察对象)是基于推送(Push)运行时执行(lazy)的多值集合。
(1) 通过 构造方法创建
/--js---
import $ from
'jquery'
;
import Rx from
'rxjs/Rx'
;
const source$ =
new
Rx.Observable(
observe => {
console.log(
'creating observable'
);
//更新 数据流
observe.next(
'hello rxjs'
);
observe.next(
'another value'
);
observe.error(
new
Error(
'Error: Something went wrong!'
))
setTimeout(() => {
observe.next(
'yet another value'
);
observe.complete();
}, 2000)
}
);
source$
.
catch
(err => Rx.Observable.of(err))
.subscribe(
x => {
console.log(x);
},
err => {
console.log(err);
},
complete => {
console.log(
'complete'
);
}
);
|
(2) 从事件创建, 实现一个简单的input输入 => 数据更新
//---html---
<input id=
"input"
>
<p id=
"inputVal"
></p>
/--js---
import $ from
'jquery'
;
import Rx from
'rxjs/Rx'
;
const input = $(
'#input'
);
const inputVal = $(
'#inputVal'
);
const inputSource$ = Rx.Observable.fromEvent(input,
'keyup'
);
inputSource$.subscribe(
//捕获的值
(e) => {
inputVal.html(e.currentTarget.value);
},
//捕获的错误
(err) => {
console.log(
'err: '
, err);
},
//完成
() => {
console.log(
'Complete'
);
}
);
|
(3) 从 promise 创建
/--js---
//普通的 promise 封装
import $ from
'jquery'
;
import Rx from
'rxjs/Rx'
;
const myPromise =
new
Promise((resolve, reject) => {
console.log(
'create promise!'
);
setTimeout(() => {
resolve(
'hello from promise!'
);
}, 3000)
});
const promiseSource$ = Rx.Observable.fromPromise(myPromise);
promiseSource$.subscribe(x => console.log(x));
// ajax 数据请求
function
getUser(username) {
return
$.ajax({
dataType:
'jsonp'
}).promise();
}
Rx.Observable.fromPromise(getUser(
'wikidson'
))
.subscribe( x => {
console.log(x);
});
|
(4)从 array 创建
/--js---
//普通的 promise 封装
import $ from
'jquery'
;
import Rx from
'rxjs/Rx'
;
从 promise 创建
/--js---
//普通的 promise 封装
import $ from
'jquery'
;
import Rx from
'rxjs/Rx'
;
const myPromise =
new
Promise((resolve, reject) => {
console.log(
'create promise!'
);
setTimeout(() => {
resolve(
'hello from promise!'
);
}, 3000)
});
const promiseSource$ = Rx.Observable.fromPromise(myPromise);
promiseSource$.subscribe(x => console.log(x));
// ajax 数据请求
function
getUser(username) {
return
$.ajax({
dataType:
'jsonp'
}).promise();
}
Rx.Observable.fromPromise(getUser(
'wikidson'
))
.subscribe( x => {
console.log(x);
});
|
5. 使用场景
(1)click event
如果我们想要能够抓取single click 与 double click 的事件,用最早的javascript 可能会需要变量来记录状态、时间等,但通过RxJS 提供的api,实现如下:
/--js---
//普通的 promise 封装
import $ from
'jquery'
;
import Rx from
'rxjs/Rx'
;
从 promise 创建
/--js---
//普通的 promise 封装
import $ from
'jquery'
;
import Rx from
'rxjs/Rx'
;
const multiClickStream = clickStream$.bufferWhen(() => clickStream$.debounceTime(250))
.map((list) => list.length)
.filter((len) => len === 2);
multiClickStream.subscribe(
(numClicks) => {
console.log(numClicks);
}
);
|
从上图可以看出,RxJS 帮我们把 stream 上的event 依照我们想要的时间做整理,buffer 住 触发时间在 250ms 间的 click events ,并且利用map函数抓出每个 event list 的长度, 并进一步 筛选出 长度等于 2 ,也就是 double click 的event 出来。