rxjs-响应式编程类库)RxJS官网
RxJS(Reactive Extensions For JavaScript是ReactiveX编程理念的JavaScript版本。
rx把事件和数据看成一个流,所有的操作都是异步的,可以把RxJS想成处理异步行为的Lodash。
简单来说,它将一切数据,包括HTTP请求,DOM事件或者普通数据等包装成流的形式,然后用强大丰富的操作符对流进行处理,使你能以同步编程的方式处理异步数据,并组合不同的操作符来轻松优雅的实现你所需要的功能。
- 纯函数的特性
没有返回值;不会改变原数据;(输入一定、输出也一定)
const arr = [1,2,3,4,5];
arr.slice(0,3);//arr不变,slice就是纯函数
arr.splice(0,3,2);//arr被改变,splice不是纯函数
rxjs初体验——控制点击频率,每次点击间隔1S以上
- 原生实现
let count = 0;
let rate = 1000;
let lastClick = Date.now() - rate;
document.addEventListener('click', ()=>{
if(Date.now() - lastClick >= rate){
console.log(`Clicked ${++count} times`);
lastClick = Date.now();
}
})
- rxjs实现
import { fromEvent } from 'rxjs'
import { throttleTime, scan } from 'rxjs/operators'
fromEvent(document, 'click').
pipe(
throttleTime(1000),
scan(count => count + 1, 0)
)
.subscribe(count => console.log(`click ${count} times`)
)
rxjs和promise
- 可观察对象是声明式的,在被订阅之前,它不会开始执行;而promise是在创建时就立即执行的。
class AppComponent{
newPromise(){
const p = new Promise(resolve => {
console.log('initial a promise');//立即触发
})
}
newObservable(){
const o = new Observable(subscriber => {
console.log('initial a newObservable');//不触发
})
}
}
- 串联,和上一条类似,只有当调用subscribe方法时,才会执行所有管道函数
class AppComponent{
newPromise(){
const p = new Promise(resolve => {
console.log('initial a promise');//立即触发
resolve(['a','b,','c'])
}).then(res => {
console.log('第一个then')
return res;
}).then(res => {
console.log('第二个then')
return res;
})
}
newObservable(){
const o = new Observable(subscriber => {
console.log('initial a newObservable');//不触发
subscriber.next(['a','b','c'])
}).pipe(
map(res => {
console.log('第一个map')
return res;
}),
map(res =>{
console.log('第二个map')
return res;
})
);//不订阅,pipe中的所有函数都不会触发
}
}
- Observable可以手动取消,Promise被解析时自动完成
const sub = interval(1000).subscribe(res => {
console.log('interval', res);
});
class App{
calcelObservable(){
sub.unsubscribe();
}
}
rxjs与原生js的区别
- concat
类似于forEach,可以用在循环中
const arr$ = from(['a', 'b', 'c']);
const arr2$ = from(['1', '2', '3']);
concat(arr$, arr2$).subscribe(res => {
console.log('concat', res)
})
//concat a
//concat b
//concat c
//concat 1
//concat 2
//concat 3
- filter
const arr$ = from(['a', 'b', 'c']);
const arr2$ = from([1, 2, 3, 4]);
concat(arr$, arr2$).pipe(filter(item => item > 2)).subscribe(res => {
//整理过滤大于3的数字
console.log('concat', res)
})
- reduce
from([1, 2, 3, 4]).pipe(reduce((s, v) => s + v)).subscribe(res => {
console.log('concat', res)
})
//10
- scan
与reduce不同,返回的是每一次的结果
from([1, 2, 3, 4]).pipe(scan((s, v) => s + v)).subscribe(res => {
console.log('concat', res)
})
//concat 1
//concat 3
//concat 6
//concat 10
网友评论