问题描述
我正在使用ngrx8,rxjs6和angular 9
登录后,我需要致电其他服务。当该服务引发错误时,我想catchError来处理它的部分问题,问题是我在try catch中捕获了错误,并且看到了日志,但是未触发catchError
。
简化代码
login$ = createEffect(() => {
return this.actions$.pipe(
ofType(AuthActions.login),switchMap((action) =>
this.userService.login(action.userName,action.password)
.pipe(
switchMap((token) => {
return throwError(new Error('hello'));
}),map((token) => AuthActions.loginSuccess()),catchError((error) => {
console.error('error',error); // I don't see this in console
return of(AppError({ error }));
})),),catchError((error) => {
console.error('error 2',error);
return of(AppError({ error }));
}),);
});
我的真实代码
login$ = createEffect(() => {
return this.actions$.pipe(
ofType(AuthActions.login),action.password)
.pipe(
switchMap(async (token) => {
try {
await this.matrixService.initClient(action.userName,action.password);
return of(token);
}
catch (error) {
console.log('catch error',error); // I see this in console
return throwError(error);
}
}),);
});
控制台输出
解决方法
而不是使用Async-Await
语法来等待Promise
返回的matrixService.initClient
的完成(由于switchMap
运算符未等待,因此在当前上下文中不起作用对于async
函数),请考虑不等待它就将其返回,因为它将被转换成Observable
(由于switchMap
运算符接受Promise
),从而导致{{1 }}正在等待。
this.userService.login
,
根据评论,我将对先前的答案进行一些修改
login$ = createEffect(() => this.actions$
.pipe(
ofType(AuthActions.login),switchMap(({ userName,password }) => this.userService.login(userName,password)
.pipe(
map((token) => AuthActions.loginSuccess())
tap(() => this.matrixService.initClient(userName,password)),)
),catchError((error) => {
console.error('error 2',error);
return of(AppError({ error }));
})
)
);
我切换顺序,总是先触发AuthActions.loginSuccess()
,然后触发this.matrixService.initClient(userName,password)
。
catchError
不需要被调用两次,服务调用生成的任何错误都将被最外层的catchError
运算符捕获。