3

我正在努力掌握 NgRx 效果。

使用最新版本,版本 8,我编写了以下效果,它将 observable 与 promise 相结合,并且正在努力掌握如何正确编写它。

这可以保证捕获所有可能的错误吗?

authLogin$ = createEffect(() => this.actions$.pipe(
    ofType(AuthActions.authLogin),
    switchMap(async(action) => {
      try {
        const userState = await this.loginService.login(action.username, action.password);
        return AuthActions.authSuccess(userState);
      }
      catch (error) {
        return AuthActions.authLoginError({
          error: error
        });
      }
    })
  ),{ resubscribeOnError: false });

我也不清楚我是否应该使用此配置的最后一位:这{ resubscribeOnError: false }是否意味着后续执行将创建一个全新的 observable?

有更好的方法吗?

4

1 回答 1

6

我不确定这是否try catch会捕获所有错误,因为我只看到了带有.then().catch()的 Promise,但是为什么不将此 Promise 转换为 Observable?它会让你pipe更容易写作和正确写作。

使用 yourswitchMap从 Promise 中返回 Observable

import {from} from 'rxjs';

...
switchMap(action => from(this.loginService.login(action.username, action.password)))
...

之后,您可以拥有catchError来自 RxJs 的 Observable 运算符。您会收到错误和一个名为 的属性caught,它是可观察的源(来自此处的文档)。在那里你可以

...
catchError((err, caught$) => {
  this.store.dispatch(new AuthActions.authLoginError({ error: error }));
  return caught$;
})
...

return caught$如果发生错误,这很重要,因为您可以防止效果死亡。你不需要在 NgRx 8 上那样处理,你可以简单

...
catchError((err, caught$) => {
  return of(new AuthActions.authLoginError({ error: error })));
})
...

但是你需要你的{ resubscribeOnError: true }(这是默认值)。如果您不处理错误,这是一个重新订阅您的效果的功能,再次防止它死亡。

然后,在你之后catchError,你可以有一个简单map的成功回报,就像这样

...
map(userState => new AuthActions.authSuccess(userState))

因此,您完成的代码将如下所示

authLogin$ = createEffect(() => this.actions$.pipe(
  ofType(AuthActions.authLogin),
  switchMap(action => from(this.loginService.login(action.username, action.password))),
  catchError((err, caught$) => of(new AuthActions.authLoginError({ error: error })))),
  map(userState => new AuthActions.authSuccess(userState))
)); // no resubscribeOnError since default value is true

我会说这是一种更好的方法,因为使用 Observable 进行服务调用,您可以让操作员分离职责并使 NgRx 满意。

于 2019-08-19T00:40:52.497 回答