Rxjs:"throw" 语句未被管道 catchError 处理

Rxjs: "throw" statement not being handled by piped catchError

A "authenticationService" 提供了以下身份验证方法。我无法输入管道 catchError。我错过了什么?

authenticate(credentials: { username: string; password: string }){

   return new Observable<any>((observer: Observer<any>) => {

    // ... calling the service, obtaining a promise
    const authenticationPromise = ... ;

    // This is a promise, it must be converted to an Observable
    authenticationPromise
        .then(() => {
          observer.next('ok');
          observer.complete();
        })
        .catch(err => {
          console.log('service error ' + err);
          throw new Error('crap');
        });
    });
  }

将所有 ngrx 和 ngrx/effect 部分放在一边,根据用户请求调用此身份验证方法:

(redux stuff).(({ payload }: actions.LoginRequestAction) =>
    context.authService.authenticate(payload)
    .pipe(
      map(() => new GenericSuccessAction(...))
      // Even though a throw statement happened in the authenticate method, this is never reached:
      catchError((err: Error) => {
        console.log('[debug] error caught: ', err);
        return of(new actions.LoginFailureAction());
      }),
    )
  )

As stated here, catchError is used to:

Gracefully handle errors in an observable sequence.

首先,您基本上是通过捕获承诺中的错误来处理承诺中的错误。在 promise 中抛出错误不会 return 一个发出错误的可观察对象。

您可以:

  1. 将您的 promise 转换为 observable 并且完全不使用 .catch
  2. Return 使用 rxjs 可观察到的错误 throwError(err)

无论哪种方式,您创建 observable 的方式都值得怀疑。

这是在 rxjs 中处理 promise 的一种更好、更简洁的方法:

from(authenticationPromise)
    .pipe(
         map(() => 'ok')
    )