在Angular中,内置了很多可观察(Observable)对象,这些对象具有可订阅性,当有消费者调用subscribe()方法时,这个函数就执行,普遍用于前端请求处理的场景。本篇暂时脱离Angular,集中到rxjs本身的api操作符上,挑选最常见的操作符作为demo。
操作符
按照类型划分为 组合
、条件
、创建
、错误处理
、过滤
、多播
、转换
、工具
创建一个 Observable
create
import { Observable,from } from 'rxjs';
const content = Observable.create((observer)=>{
observer.next('something');
});
from
import { Observable,from } from 'rxjs';
const source = from([1,2,3,4]);
fromEvent
将事件转成 Observable 序列
import { fromEvent } from 'rxjs';
const source = fromEvent(document, 'click');
source.subscribe(val => {
console.log(val);
})
of
按顺序发出任意数量的值
import { of } from 'rxjs';
const source = of(1,2,3,4);
其他:empty
立即完成
const subscribe = empty().subscribe({
next:()=>console.log('next'),
complete:()=>console.log('complete')
});
interval
基于给定时间间隔发出数字序列
source.subscribe(res=>{
console.log(res);
});
timer
给定一定的时间后,根据第二参数时间间隔发出值,缺失第二参数,则只发出一次值
const source = timer(1000,500);
source.subscribe(res=>{
console.log(res);
});
过滤操作
filter
类似数组的操作api,挑选符合条件的进行返回
比如从一组返回的数据中筛选符合的样本,原本的做法是订阅者将数据全部获取进行筛选,这份工作可以转移到filter操作中进行,订阅者拿到的就是符合预期的数据。
const source = from([1, 2, 3, 4, 5, 6]).pipe(filter((o: number) => o > 3));
source.subscribe(res=>{
console.log(res);
});
take
在完成前指定发出N个值
如:首次点击有效
const oneClickEvent = fromEvent(document, 'click')
.pipe(
take(1)
);
oneClickEvent.subscribe(event => {
console.log(event);
});
转换(核心)
map
对每个源observable的每个值应用投射函数(加工处理,格式转换、补全等)
const source = from(['abc', 'DEf', 'cDt']).pipe(
map((o: any) =>
o.toLocaleLowerCase()
)
);
source.subscribe(res=>{
console.log(res);
});
switchMap
和其他打平操作符的主要区别是它具有取消效果。在每次发出时,会取消前一个内部 observable (你所提供函数的结果) 的订阅,然后订阅一个新的 observable 。你可以通过短语切换成一个新的 observable来记忆它。
应用:拦截后处理,取消之前发出但还未结束的订阅操作。
模拟两个按钮发起可订阅的操作(如http请求)
const mapBtn = window.document.getElementsByClassName('btn');
const switchMapBtn = window.document.getElementsByClassName('switchMap');
const interval$ = interval(1000);
let mapClickCount = 0;
let switchMapCount = 0;
const source = fromEvent(mapBtn, 'click')
.pipe(
map(event => {
mapClickCount++;
return interval$;
}),
);
source.subscribe((observal) => {
observal.subscribe(res => {
console.log(`map clickCounts: ${mapClickCount},and res is ${res}`);
})
});
const switchMapSource = fromEvent(switchMapBtn, 'click')
.pipe(
switchMap(event => {
switchMapCount++;
return interval$;
}),
);
switchMapSource.subscribe(res => {
console.log(`switchMap clickCounts: ${switchMapCount},and res is ${res}`);
})
点击第一个普通订阅按钮2次(间隔1s):
对比使用switchMap的按钮:
图2中每次按钮点击都会取消之前的订阅数值,重新计算。
工具
toPromise
将 obeservable转换成promise。
const source = from([1, 2, 3]);
const promise: Promise<any>[] = [];
source.pipe(
map(o => {
return of(o).toPromise()
})
).subscribe(res => {
promise.push(res);
});
Promise.all(promise).then(res=>{
console.log(res); //[1,2,3]
});
delay
延迟时间
const source = from([1, 2, 3]);
source.pipe(
map(o => {
console.log(new Date().getSeconds());
return o;
}),
delay(5000)
).subscribe(res=>{
console.log(`${new Date().getSeconds()} ${res}`);
});
tap
5.5v以前的do操作符重命名,使用场景:输出执行日志等
const source = from([1, 2, 3]);
source.pipe(
tap(o => console.log(o)),
map(o => {
return o;
}),
).subscribe(res => {
console.log(`${res}`);
});
Rxjs学习网址:https://cn.rx.js.org/class/es6/Observable.js~Observable.html
翻译网站:
https://rxjs-cn.github.io/learn-rxjs-operators/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。