angular的rxjs中的操作符
目录
前言
一、take和interval操作符
二、mergeMap
三、forkJoin
四、catchError
五、timer
六、takeUntil
七、defer
八、zip
九、concatMap
十、concat
前言
rxjs是一个用于处理异步数据流的一个库,以下是该库中部分的操作符
一、take和interval操作符
take操作符(只取前n个发出的值)和interval(每间隔n毫秒,发出递增的数字0,1,2...n)
//每隔一秒输出从0开始的数字,take表示输出前10个数字,最后得到的结果是输出了0-9的数字interval(1000).pipe(take(10)).subscribe((result) => {console.log(result);});
二、mergeMap
//前序结果发出hellow时,结合hello返回一个可观察对象,最后调用得到结果输出hello worldof('hello').pipe(mergeMap((value) => {return of(value + ' world');})).subscribe((result) => {console.log(result); //输出 hello world});
三、forkJoin
等待所有函数执行完成并收集最终结果,严格等待所有可观察对象执行完毕。仅保留每个Observable的最后发出值,输出结果与传参类型一致,如果传参为数组则输出数组,为对象则输出对象。
注意事项:
- 若任一Observable未完成(如HTTP请求被取消)则永远不会输出
- 若任一Observable出错则立即终止并传递错误
- 空Observable会导致无输出(需确保所有输入都会发出值)
forkJoin([of(1, 2, 3, 4), of(4, 5, 6, 7)]).subscribe((result) => {console.log(result); //[4,7]输出两个Observable的最后发出值,4,7});/**解构赋值**/forkJoin([of(1, 2, 3, 4), of(5, 6, 7)]).subscribe(([user1, user2]) => {console.log(user1, user2); //4,7输出两个Observable的最后发出值,4,7});/**对象形式的解构赋值**/forkJoin({ user1: of(1, 2, 3, 4), user2: of(5, 6, 7) }).subscribe(({ user1, user2 }) => {console.log(user1, user2); //4,7输出两个Observable的最后发出值,4,7});/**此情况不会输出任何值**/forkJoin([of(1, 2, 3, 4), of()]).subscribe((result) => {});
四、catchError
捕捉错误并返回可观察对象
of(new Error('error')).pipe(catchError((error) => {return of(error);})).subscribe((result) => {console.log(result); //输出错误});
五、timer
/**1.单参数 timer(3000) 表示延迟3s发出0结束 */timer(3000).subscribe((result) => {console.log(result); //输出0});/**2.双参数 timer(3000,1000) 表示延迟3s后每隔一秒发出值,值为数字自然递增0,1,2....n */timer(3000, 1000).subscribe((result) => {console.log(result); //输出0,1,2,3,4...n});
六、takeUntil
允许前一个Observable持续发出值,直到takeUntil里开始发出值,只要takeUntil里开始发出值,就会阻碍前面的观察对象发出
const obser1 = interval(1000); //每隔一秒发出值const obser2 = timer(5000); //延迟5s后发出值obser1.pipe(takeUntil(obser2)).subscribe((result) => {console.log(result); //输出0,1,2,3,4 第五秒obser2开始发出值,obser1停止发出值});
七、defer
必须接收一个工厂函数,返回一个Observable或者promise(RxJS 会自动转换为 Observable)
const deferInfo = defer(() => {console.log('我只有在被调用的时候才能执行');//订阅后再执行return interval(1000);//每隔一秒输出数字0,1,2,3...n});console.log('我会先执行');//先执行deferInfo.subscribe((result) => {console.log(result);});
八、zip
严格按照顺序,将多个Observable发出的值按顺序合并,一对一的样式,输出为数组形式,如果相同顺序的值还没有输出,则会等待一起输出
zip(of(1, 2, 3, 4),timer(2000, 1000).pipe(take(4)),of(9, 10, 11, 12)).subscribe((result) => {//首次输出会延迟2s后依次输出所有合并值console.log(result); //[1,0,9],[2,1,10],[3,2,11],[4,3,12]});
九、concatMap
接收一个函数,返回值是obserable或者promise(会自动转换为Observable),严格按照发射源的顺序,concatMap内部前一个Observable执行完毕才会执行concatMap里的下一个
//of的操作室依次调用next同步输出值,concatMap会确保内部的前一个Observable完成后再调下一个
//值发射是同步且即时的,但后续操作符(如 concatMap)可能引入异步行为
of(1, 2, 3, 4).pipe(concatMap((value) => {return of('user/' + value);})).subscribe((result) => {console.log(result);});
十、concat
会按顺序订阅每一个输入的 Observable,只有当前一个 Observable 完成后才能订阅下一个Observable
适合情况:两个接口,需要前一个接口完成后才调用下一个接口
concat(timer(5000), of(6, 7, 8, 9)).subscribe((result) => {console.log(result); // 第五秒输出0后才开始输出6,7,8,9});