我有一个Angular应用程序和Nrwl的NgRx和Nx。Nx提供了几个";数据持久性";可以帮助您获取、乐观和悲观地更新以及处理导航的函数,但我不确定为什么要使用它们而不是普通的管道。
下面是StackBlitz上的一个例子,显示了使用optimisticUpdate
和pessimisticUpdate
的一些效果,以及在没有它们的情况下做同样事情的其他效果。
问题是,这些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
选择器函数。看看这里的例子。在我自己的测试中,如果多次调度一个操作,则除非使用id
选择器,否则每个请求都会通过。一旦你添加了它,如果新的操作带有相同的ID,fetch
将取消任何现有的网络请求。
此功能可以通过简单的switchMap
运算符获得,但fetch
实用程序还有switchMap
没有提供的另一个优点:在网络请求进行时,使用不同的ID调度操作不会取消当前请求。
考虑以下示例:
this.store.dispatch(getUser('AAA'));
this.store.dispatch(getUser('BBB'));
this.store.dispatch(getUser('AAA'));
对于switchMap
,只有最后一个请求会通过,所以您永远不会成功获取用户BBB
。但是,对于fetch
,最后两个请求将通过。