我如何编写一个 NgRx 8 Effect 来触发一个 Promise 的动作

Dev*_*ike 3 asynchronous promise observable ngrx angular

我正在努力掌握 NgRx 效果。

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

这是否保证捕获所有可能的错误?

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 });
Run Code Online (Sandbox Code Playgroud)

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

有没有更好的方法?

Joã*_*tti 6

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

使用你switchMap的从你的 Promise 返回一个 Observable

import {from} from 'rxjs';

...
switchMap(action => from(this.loginService.login(action.username, action.password)))
...
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

...
map(userState => new AuthActions.authSuccess(userState))
Run Code Online (Sandbox Code Playgroud)

所以,你完成的代码看起来像这样

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
Run Code Online (Sandbox Code Playgroud)

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

  • 该效果不会第二次触发。请帮助如何使用 ngrx v8 效果多次触发。 (2认同)