angular - 使用 Nrwl 的 Nx 中的数据持久性模块,悲观更新的实现与乐观更新有何不同
问题描述
我们正在为我们的 Angular 应用程序采用 Nrwl.io 的 Nx 框架。
作为其中的一部分,我们试图了解数据持久性模块中的optimisticUpdate 和pessimisticUpdate 方法之间的底层实现差异。
根据文档,pessimisticUpdate 将在客户端之前更新服务器,而使用optimisticUpdate,客户端首先更新。
然而,这两种方法在 github 上的源代码如下
export function pessimisticUpdate<T, A extends Action>(
opts: PessimisticUpdateOpts<T, A>
) {
return (source: ActionStateStream<T, A>): Observable<Action> => {
return source.pipe(
mapActionAndState(),
concatMap(runWithErrorHandling(opts.run, opts.onError))
);
};
}
export function optimisticUpdate<T, A extends Action>(
opts: OptimisticUpdateOpts<T, A>
) {
return (source: ActionStateStream<T, A>): Observable<Action> => {
return source.pipe(
mapActionAndState(),
concatMap(runWithErrorHandling(opts.run, opts.undoAction))
);
};
}
从表面上看,将更新分为乐观和悲观似乎非常有用,但本质上这两种方法的实现似乎是相同的,我们正在努力理解这两种方法的含义。
此外,当 run 方法成功完成时,调用optimisticUpdate 方法的示例代码不会调度操作。我的理解是这将结束流 - 没有迹象表明后端调用应该返回什么。
class TodoEffects {
@Effect() updateTodo = this.s.optimisticUpdate('UPDATE_TODO', {
// provides an action and the current state of the store
run: (a: UpdateTodo, state: TodosState) => {
return this.backend(state.user, a.payload);
},
undoAction: (a: UpdateTodo, e: any) => {
// dispatch an undo action to undo the changes in the client state
return ({
type: 'UNDO_UPDATE_TODO',
payload: a
});
}
});
任何一直在使用 Nx 的人都可以了解其中的区别以及我们需要在我们的服务中执行哪些操作以实现乐观的更新。
解决方案
Nx 带有两个版本:RxJs pipeable operator
DataPersistence 类的一个版本和一个成员。
前者需要一个 Observable 来管道,您需要提供它(这些是您在第一个代码块中找到的函数)。后者看起来像您的第二个代码块。
实现的乐观和悲观之间的区别仅在于可以回滚乐观更新(提供undoAction
)。这是因为在乐观调用中,我们立即更新 UI 并发送网络调用来更新服务器。如果服务器调用不成功,我们需要回滚我们所做的 UI 更改。这不适用于悲观的调用,因为我们有一个加载微调器或其他机制来避免在调用过程中更新 UI。
对于您的第二个代码块,该run
函数未返回操作。这应该在 Nx 文档中更新。
class TodoEffects {
@Effect() updateTodo = this.s.optimisticUpdate('UPDATE_TODO', {
run: (a: UpdateTodo, state: TodosState) => {
return this.backend(state.user, a.payload)
.pipe(
map(resp => ({
type: 'UPDATE_TODO_SUCCESS',
payload: resp
}))
);
}
推荐阅读
- spring - Spring Boot,我什至需要一个带有 vuejs 的模型吗?
- android - 在 Android 上使用 algolia 使 Firebase 实时数据库可搜索
- mongodb - 使用 Mongoose 保存时的 JSON 格式无法恢复预期结果
- recursion - 如何制作将相同命令应用于子目录的单个makefile?
- java - Spock 断言对象列表在字段中具有精确值
- python - 在python pandas df中将月份数转换为名称
- amazon-web-services - 如何使用 CodeDeploy 将我在 bitbucket 中的存储库部署到 AWS?
- python - 表单中的 Django DRY 函数
- amazon-web-services - 亚马逊 EC2 ebs 与 gp2 ami
- spring-jms - 使用 @JmsListener 时的 setExceptionListener