简体   繁体   English

我如何编写NgRx 8效果来触发诺言中的动作

[英]How do i write an NgRx 8 Effect that triggers an action from a promise

I am struggling to grasp NgRx Effects. 我正在努力掌握NgRx效果。

Using the latest release, version 8, i have written the following effect which combines the observable with a promise and am struggling to grasp how to write it correctly. 我使用最新的版本8编写了以下效果,该效果将可观察的内容与承诺相结合,并且努力掌握如何正确编写它。

Is this guaranteed to catch all possible errors? 是否可以保证捕获所有可能的错误?

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 });

I am also not clear on whether or not i should be using the last bit of this configuration: { resubscribeOnError: false } Does this mean subsequent execution will create an entirely new observable? 我也不清楚我是否应该使用此配置的最后一位: { resubscribeOnError: false }这是否意味着后续执行将创建一个全新的可观察对象?

Is there a better approach? 有没有更好的方法?

I'm not sure if this try catch will catch all errors, cause I've only seen Promises with .then().catch() , but why don't you convert this Promise to an Observable? 我不确定此try catch是否会捕获所有错误,因为我只用.then().catch()看过Promises,但是为什么不将此Promise转换为Observable呢? It'd make your pipe easier to write and to write properly. 这会使您的pipe更易于编写和正确编写。

Use your switchMap to return an Observable from your Promise with 使用您的switchMap从您的Promise中返回一个Observable

import {from} from 'rxjs';

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

After that you can have your catchError , an Observable operator from RxJs. 之后,您可以使用catchError中的Observable运算符catchError。 You receive the error and a property called caught , which is the source observable (from docs here ). 您会收到错误和一个名为caught的属性,该属性是可观察到的源(来自docs 此处 )。 Where you can 在那里你可以

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

The return caught$ is important cause you prevent your Effect from dying if an error occurs. return caught$是重要的原因,因为如果发生错误,可以防止效果死亡。 You don't need to handle like that on NgRx 8, you could simple 您不需要像在NgRx 8上那样处理,您可以简单

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

But then you'd need your { resubscribeOnError: true } (which is the default value). 但随后您将需要{ resubscribeOnError: true } (这是默认值)。 This is a feature that resubscribe on your Effect if you don't handle errors, once again preventing it from dying. 如果您不处理错误,此功能将在您的效果上重新订阅,再次防止它死亡。

And then, after your catchError , you can have a simple map to return on success, like this 然后,在catchError ,您可以拥有一个简单的map以返回成功,像这样

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

So, your finished code will look like this 因此,您完成的代码将如下所示

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

I'd say this is a better approach since utilizes an Observable for your service call, you have operators separating responsibilities and makes NgRx happy. 我想说这是一种更好的方法,因为利用Observable进行服务呼叫,让操作员将职责分开,并使NgRx开心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM