在 NgRX Effect 中处理时,效果将不再起作用

When handling in NgRX Effect, the effect won't work anymore

我这辈子都想不通为什么一旦抛出并拦截了错误,效果就失效了

  @Effect()
  register$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(RegisterAction),
      map(action => action.registrationInfo),
      mergeMap(registrationInfo => {
        return this.authService.createUser(registrationInfo.email, registrationInfo.password,
          registrationInfo.lastname, registrationInfo.firstname);
      }),
      map(credentialInfo => ProfileInitAction({credentialInfo})),
      catchError(error => [ProfileInitErrorAction(error)]),
    );
  });

在 catchError 中添加 caught$ 似乎可以解决这个问题。

  register$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(RegisterAction),
      map(action => action.registrationInfo),
      mergeMap(registrationInfo => {
        return this.authService.createUser(registrationInfo.email, registrationInfo.password,
          registrationInfo.lastname, registrationInfo.firstname);
      }),
      map(credentialInfo => ProfileInitAction({credentialInfo})),
      catchError((err, caught$) => {
        notify(this.translate.instant('pages.auth.register.notify.error' + ': ' + err['message']), 'error');
        return caught$;
      }),
    );
  });

你知道为什么吗?因为这是 RXJS 中的正常工作流程。因此,可观察对象会在不同时间发出值。当发生错误时,可观察链(或管道或订阅,或您想要的)就会中断。你有一个服务电话。这个服务调用可能会失败,对吧?但是您在 child 可观察链中执行此服务调用。所以你可以处理这个 child 的可观察链中的错误,这不会破坏你的主要可观察链。一句话,做mergeMap中的catchError

例如:

import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { EMPTY } from 'rxjs';
import { map, mergeMap, catchError } from 'rxjs/operators';
import { MoviesService } from './movies.service';

@Injectable()
export class MovieEffects {

  loadMovies$ = createEffect(() => this.actions$.pipe(
    ofType('[Movies Page] Load Movies'),
    mergeMap(() => this.moviesService.getAll() //< --- starting point of the child observable chain
      .pipe(
        map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
        catchError(() => EMPTY) // <--- this is runs in the child observable chain
      ))
    ) // <--- end of the child observable chain
  ); // <--- end of the main observable chain

  constructor(
    private actions$: Actions,
    private moviesService: MoviesService
  ) {}
}