ngrx 효과의 switchMap에서 오류를 throw하는 방법
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),
switchMap((action) =>
this.userService.login(action.userName, 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);
}
}),
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 }));
}),
);
});
콘솔 출력

답변
오히려 사용하는 것보다 Async-Await
기다릴 구문 Promise
에 의해 반환 matrixService.initClient
(때문에 현재 상황에서 작동하지 않을 것이다 전체에 switchMap
운영자가 기다리고하지 async
그것을가로 변환하는 것처럼, 그것을 기다리지 않고 그것을 반환 고려, 기능) Observable
에 (감사 switchMap
연산자 수락 Promise
) 결과 this.userService.login
로 기다리고 있습니다.
login$ = createEffect(() => this.actions$
.pipe(
ofType(AuthActions.login),
switchMap(({ userName, password }) => this.userService.login(userName, password)
.pipe(
switchMap(() => this.matrixService.initClient(userName, password)),
map((token) => AuthActions.loginSuccess()),
catchError((error) => {
console.error('error', error);
return of(AppError({ error }));
})
)
),
catchError((error) => {
console.error('error 2', error);
return of(AppError({ error }));
})
)
);
댓글에 따라 이전 답변을 조금 수정하겠습니다.
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 }));
})
)
);
I switch the order, always firing AuthActions.loginSuccess()
and then this.matrixService.initClient(userName, password)
.
catchError
does not need to be called twice, any error generated from service call will be catch in the outermost catchError
operator.