Abstract
Rxjs是Angular框架的官方推荐异步处理库,其内置丰富的operators,运算子,能够帮助我们解决大部分的业务难题。
学习前置条件
- Observable 可观察的抽象接口,需要有next等方法,可以被订阅的。
- Observer 观察者,可以不定时地发送新事件,有next, error, complete等方法。
- Subscriber 订阅者,订阅了观察者,当观察者发出新事件时,订阅者的内容会自动触发执行。
- Pipe 管道,事件流的载体。
- Operator 运算子,有几种不同分类的,比如创建型,操控型,错误处理型。
Vs Promise
- 状态改变区别 Promise的状态只能被改变一次,也就是then里面的方法只会执行第一次。而Observer.next()可以发送多次新值,其订阅的方法也会跟着执行多次,只有Observer.complete()后,这个观察者的状态才终止,next不会再触发新的事件。
- 回调函数区别 一个变化多个响应时,promise需要.then进行添加多个处理,而Observer可以直接subscribe()多次,来实现多个回调方法。
演示
基础请求
新建request.ts:
import { Observable } from 'rxjs';
export function request(url: string) {
return new Observable((observer) => {
setTimeout(() => {
observer.next(url + 'respone');
observer.complete();
}, 1000);
});
}
export function badRequest(url: string) {
return new Observable((observer) => {
setTimeout(() => {
observer.error(url + '500 Server');
observer.complete();
}, 1000);
});
}
component.ts:
import { badRequest, request } from 'src/app/request';
ngOnInit() {
request('test.com').subscribe({
next: (res) => console.log('成功: ', res),
error: (err) => console.log('失败: ', err),
complete: () => console.log('完成'),
});
badRequest('test2.com').subscribe({
next: (res) => console.log('成功: ', res),
error: (err) => console.log('失败: ', err),
complete: () => console.log('完成'),
});
}
效果:
基础请求 + operator
import { catchError, of } from 'rxjs';
request('test.com')
.pipe(
catchError((err) => {
console.log('接口错误');
return of(err);
})
)
.subscribe((res) => console.log(res));
badRequest('test2.com')
.pipe(
catchError((err) => {
console.log('接口错误');
return of(err);
})
)
.subscribe((res) => console.log(res));
效果:
串行请求 + 高阶Observable
import { mergeMap } from 'rxjs';
import { request } from 'src/app/request';
request('foo')
.pipe(
mergeMap((res) => {
console.log('res1: ', res);
return request('bar');
}),
mergeMap((res) => {
console.log('res2: ', res);
return request('bazz');
})
)
.subscribe((res) => console.log('res3: ', res));
效果:
Tip: switchMap,concatMap,mergeMap都是用来处理返回Observable对象的Observer,这里当源observer只发送一个事件时,这些运算子的表现形式是一样的。
串行请求 + 高阶Observable + 捕获错误
import { catchError, mergeMap, throwError } from 'rxjs';
import { badRequest, request } from 'src/app/request';
const pipeErrorHandler = function (message: string) {
return catchError((err) => {
if (err && err.bad) {
// 前面已有错误,且已被处理,直接return
return throwError(() => err);
}
console.log(message);
console.log('err: ', err);
// 处理error
// ...
return throwError(() => ({ bad: true }));
});
};
request('foo')
.pipe(
pipeErrorHandler('foo 请求失败'),
mergeMap((res) => {
console.log('res1: ', res);
return request('bar');
}),
pipeErrorHandler('bar 请求失败'),
mergeMap((res) => {
console.log('res2: ', res);
return badRequest('bazz');
}),
pipeErrorHandler('bazz 请求失败')
)
.subscribe({
next: (res) => console.log('res3: ', res),
error: (err) => {
console.log('串行请求任务失败');
},
});
效果:
并行请求-forkJoin
import { forkJoin } from 'rxjs';
forkJoin({
request1: request('foo'),
request2: request('bar'),
request3: request('bazz'),
}).subscribe({
next: (value) => console.log(value),
complete: () => console.log('complete'),
});
效果:
并行请求-forkJoin + 错误处理
forkJoin({
request1: request('foo'),
request2: request('bar'),
request3: badRequest('bazz'),
}).subscribe({
next: (value) => console.log(value),
error: (err) => console.log('有错误:', err),
complete: () => console.log('complete'),
});
效果:
Tip: forkJoin的并发是全部成功才算成功,否则,抛出一个error。
想要源码的,欢迎来访问我的代码仓:
https://gitee.com/gao-hui007/my-blogs/blob/master/docs/angular/rxjs.md#
转载请说明