NgRx 效果 - 内部 catchError 执行多次

NgRx Effect - inner catchError executes multiple times

我有一个带有 NgRx 的 Angular 应用程序,在我的一个效果中我有一个非预期的行为,结果证明是预期的,但我不知道如何修复它。

我的压缩代码是

@Effect()
detelete$ = this.actions$
  .pipe(
    ofType<fromActions.DeleteRequested>(fromActions.ActionTypes.DeleteRequested),
    map(action => action.payload.id),
    mergeMap(id =>
      combineLatest([
        of(id),
        this.rservice.deleteById(id)
          .pipe(
            catchError((err, caught$) => {
              this.store.dispatch(new fromActions.DeleteCancelled({id: id}));
              return caught$;
            })
          )
      ])
    ),
    map(([id, ]: [string, any]) => {
      return new fromActions.DeleteSuccess({id: id});
    }),
  );

我的 catchError 没有和我的 mergeMap 处于同一级别的原因是我需要我的 id 作为我的 fromActions.DeleteCancelled 操作的有效载荷。另外,我的服务只有 return 一个布尔值,所以我使用 combineLatest 将它持久化到我的 onSuccess map.

我遇到的是 catchError 执行了多次。因此,多次调度我的错误操作。
我发现

If you return this source, the observable will effectively restart all over again and retry

在这种情况下,source 是我的 caught$

如果,在我的cacthError里面我return

  return of(new fromActions.DeleteCancelled({id: id}));

它仍然会转到我的 onSuccess map。我也许可以检查 map 中的第二个参数是否是 os 类型 Actionboolean,但我认为有一种正确的方法来处理它,但我不知道它。

StackBlitz (uncomment subscribe to see infinite loop)

谢谢。

你可以考虑这种方法。您的代码可能如下所示:

import { EMPTY, of, Observable } from 'rxjs';
...

@Effect()
delete$ = this.actions$.pipe(
  ofType<fromActions.DeleteRequested>(fromActions.ActionTypes.DeleteRequested),
  map(action => action.payload.id),
  switchMap((id) => this.rservice.deleteById(id).pipe(
    switchMap(result => {
      return result ? of(new fromActions.DeleteSuccess({id: id})) : EMPTY
    }),
    catchError(error => {
      return of(new fromActions.DeleteCancelled({id: id}))
    })
  )
)

如果您的服务正在 returning true,那么会调度 DeleteSuccess 操作,否则会立即完成一个空的可观察对象。 因为 EMPTY return 是一个可观察的,所以你必须使用 switchMap,并且 of 到 return 一个可观察的动作 DeleteSuccess

如有错误,DeleteCancelled 被派遣。

另一种方法是使用 @Effect({ dispatch: false }),并手动调度所有需要的操作。

希望对您有所帮助。