Rxjs
Rxjs简单说是一种针对异步数据流的编程,它将任何数据,包括http请求,DOM事件等都包装成流的形式,然后用一些操作符对流进行处理,这样就能用同步编程的方式去处理异步数据,并实现你所需要的功能;
Rxjs核心概念
- Observable
可观察系列
- Observer
观察者
- Operator
操作符
Observable 简单说数据就在Observable中流动,你可以用各种操作符(operator)来对其进行操作,例如:
const ob = Observable.interval(1000);
ob.take(3).map(n => n * 2).filter(n => n > 2).subscribe(n => console.log(n));
2 //第2秒
4 //第3秒
描述:
第一行代码我们通过类方法interval创建了一个Observable序列,ob作为源会每隔1000ms发射一个递增的数据,即0 -> 1 -> 2。
第二行代码我们使用操作符对流进行处理的过程,
take(3)表示只取源发射的前3个数据,取完第三个后关闭源的发射;
map表示将流中的数据进行映射处理,这里我们将数据翻倍;
filter表示过滤掉出符合条件的数据,根据上一步map的结果,只有第二和第三个数据会留下来。
subscribe表示“订阅”,由于ob是一个Observable,它不会立刻发射数据,因此如果在map中打印n,是不会有任何输出的,所以它必须被“订阅”才能够触发上述过程;
observer:观察者
const ob = Observable.interval(1000);
ob.subscribe(n => console.log(n));
ob.subscribe({
next: d => console.log(d),
error: err => console.error(err),
complete: () => console.log('end of the stream')
})
描述:
subscribe中传入了一个函数,第二行代码为简写,第三行代码为
完整的函数签名;
完整的函数签名包含了一个对象被称为observer
(观察者),其中又包含3个函数,表示的是对序列结果的处理方式。
- 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
出错。
Observable.of(1).map(n => n.undefinedMethod()).catch(err => {
// 此处处理catch之前发生的错误
return Observable.of(0); // 返回一个新的序列,该序列成为新的流。
});
如何创建可观察系列?
Observable.of()
可以将普通JavaScript数据转为可观察序列Observable.fromPromise(promise)
将Promise
转化为Observable
Observable.toPromise()
将Observable
转化为Promise
Observable.fromEvent(elment, eventName)
从DOM
事件创建序列,例如Observable.fromEvent($input, 'click')
Observable.ajax(url | AjaxRequest)
发送http
请求Observable.create(subscribe)
这个属于万能的创建方法
Observable VS Promise
Promise
Promise主要是通过内部缓存和函数队列来实现的, 它通过链式调用让我们能够以同步的形式编写异步流程
Promise是立即执行的,跟添不添加链式调用没有任何关系。 实际上Promise调用resolve
的时候,内部缓存了这个值,当我们添加调用then
的时候,将这个值传递给函数并执行。
执行方式:
对于promise,无论是否调用then,promise都会被立即执行;而observables却只是被创建,并不会执行,而只有在真正需要结果的时候调用subscribe,才会被执行。
var promise = new Promise((resolve,reject)=> { console.log('promise exec'); resolve(5); });
promise.then(getData).then(getNextData).then(getNextNextData).catch(fail)...
是否可取消:
场景:点击发送按钮,向后端发起一个请求,点击取消按钮,取消发送;
Promise没有提供取消这样的接口,因此没办法操作;
observables可以被cancel
是否可多次调用:
对于promise,不论在后面怎么调用then,实际上的异步操作只会被执行一次,多次调用没有效果;但是对于observable,多次调用forEach或者使用retry方法,能够触发多次异步操作
操作单一:
observable有多种操作符可对数据进行处理,比如merge,zip,map,sum等等。
promise操作只能用then