代码之家  ›  专栏  ›  技术社区  ›  Reza

在ngrx效果中如何在switchMap中投掷

  •  0
  • Reza  · 技术社区  · 4 年前

    登录后,我需要调用另一个服务。当该服务抛出错误时,我希望捕获我处理该错误的效果的一部分,问题是我在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 }));
                }),
            );
        });
    

    enter image description here

    0 回复  |  直到 4 年前
        1
  •  1
  •   Rafi Henig    4 年前

    Async-Await 等待 Promise 退回 matrixService.initClient 完成(由于 switchMap async 函数,考虑在不等待的情况下返回它,因为它将被转换成 Observable (感谢 开关图 允诺 )导致 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 }));
        })
      )
    );
    
        2
  •  0
  •   Hamza Zaidi    4 年前

    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 不需要调用两次,服务调用生成的任何错误都将在最外层捕获 操作人员