将 Nx 的数据持久性功能与 NgRx 效果结合使用是否有任何 objective 好处?

Are there any objective benefits to using Nx's Data Persistence functions with NgRx effects?

我有一个 Angular 应用程序和 Nrwl 的 NgRx 和 Nx。 Nx 提供了一些 "Data Persistence" 函数,可以帮助您乐观和悲观地获取、更新以及处理导航,但我不确定为什么要使用它们而不是普通管道。

Here's an example on StackBlitz 显示一些带有 optimisticUpdatepessimisticUpdate 的效果,以及其他没有它们也做同样事情的效果。

问题是 - 这些 Nx 函数提供了什么优势?

作为参考,这里是 StackBlitz 的效果文件:

@Injectable()
export class CarsEffects {
  updateCarOptimistic = createEffect(() =>
    this.actions.pipe(
      ofType(CarsActions.updateCarOptimistic),
      switchMap(({ selected, oldSelected, mockError }) =>
        this.carsService.updateCar(selected, mockError).pipe(
          map(() => CarsActions.updateCarOptimisticSuccess()),
          catchError(error => {
            this.store.dispatch(
              CarsActions.updateCarOptimisticFailure({ oldSelected, error })
            );
            return of(null);
          })
        )
      )
    )
  );

  updateCarOptimisticWithNx = createEffect(() =>
    this.actions.pipe(
      ofType(CarsActions.updateCarOptimisticWithNx),
      optimisticUpdate({
        run: ({ selected, mockError }) =>
          this.carsService
            .updateCar(selected, mockError)
            .pipe(map(() => CarsActions.updateCarOptimisticWithNxSuccess())),
        undoAction: ({ oldSelected }, error) =>
          CarsActions.updateCarOptimisticWithNxFailure({ oldSelected, error })
      })
    )
  );

  updateCarPessimistic = createEffect(() =>
    this.actions.pipe(
      ofType(CarsActions.updateCarPessimistic),
      switchMap(({ selected, mockError }) =>
        this.carsService.updateCar(selected, mockError).pipe(
          map(() => CarsActions.updateCarPessimisticSuccess({ selected })),
          catchError(error =>
            of(CarsActions.updateCarPessimisticFailure({ error }))
          )
        )
      )
    )
  );

  updateCarPessimisticWithNx = createEffect(() =>
    this.actions.pipe(
      ofType(CarsActions.updateCarPessimisticWithNx),
      pessimisticUpdate({
        run: ({ selected, mockError }) =>
          this.carsService
            .updateCar(selected, mockError)
            .pipe(
              map(() =>
                CarsActions.updateCarPessimisticWithNxSuccess({ selected })
              )
            ),
        onError: (_, error) =>
          CarsActions.updateCarPessimisticWithNxFailure({ error })
      })
    )
  );

  constructor(
    private actions: Actions,
    private store: Store,
    private carsService: CarsService
  ) {}
}

注意:我并不是说这是一个关于首选语法的意见问题;只是想让我的代码尽可能高效、安全和干净,并且如果它们在幕后做一些我不知道的事情,我想使用这些函数。

可以,如果您提供 id 选择器函数。查看示例 here。在我自己的测试中,如果你多次发送一个动作,除非你使用 id 选择器,否则每个请求都会通过。添加后,fetch 将取消任何现有的网络请求,如果新操作使用相同的 ID。

此功能可以通过简单的 switchMap 运算符获得,但 fetch 实用程序还有另一个 switchMap 不具备的优势:使用 [=29] 调度操作=]different ID在进行网络请求时不会取消当前请求。

考虑以下示例:

this.store.dispatch(getUser('AAA'));
this.store.dispatch(getUser('BBB'));
this.store.dispatch(getUser('AAA'));

使用 switchMap,只有最后一个请求会通过,因此您永远不会成功获取用户 BBB。然而,对于 fetch,最后的 两个 请求将会通过。