【问题标题】:NgRx Effect - inner catchError executes multiple timesNgRx 效果 - 内部 catchError 执行多次
【发布时间】:2019-07-05 19:37:30
【问题描述】:

我有一个带有 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});
    }),
  );

我的catchErrormergeMap 不在同一级别的原因是我需要id 作为fromActions.DeleteCancelled 操作的有效负载。另外,我的服务只返回一个布尔值,所以我使用combineLatest 将它持久化到我的onSuccess map

我遇到的是这个catchError 正在执行多次。因此,多次分派我的错误操作。
我发现了

如果你返回这个源,observable 将有效地重新启动并重试

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

如果,在我的cacthError 中,我返回

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

它仍然会转到我的onSuccess map。我也许可以检查我在map 中的第二个参数是操作系统类型Action 还是boolean,但我认为有一种正确的方法来处理它,我不知道。

StackBlitz (uncomment subscribe to see infinite loop)

谢谢。

【问题讨论】:

  • 你能试试return [new fromActions.DeleteCancelled({id: id})];吗?

标签: angular rxjs ngrx ngrx-effects


【解决方案1】:

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

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

如果你的服务返回true,那么DeleteSuccess动作就会被调度,否则一个空的observable会立即完成。 因为EMPTY 返回一个observable,你必须使用switchMap,并且还使用of 来返回一个observable DeleteSuccess

如果发生错误,将调度DeleteCancelled

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

希望它会有所帮助。

【讨论】:

  • 它就像一个魅力。已标记为已接受,谢谢。
猜你喜欢
  • 1970-01-01
  • 2019-02-25
  • 2019-02-12
  • 2019-07-12
  • 2018-01-11
  • 1970-01-01
  • 2017-12-04
  • 1970-01-01
  • 2023-02-16
相关资源
最近更新 更多