使用Nrwl中Nx中的数据持久性模块,悲观更新的实现与乐观更新的实现有何不同



我们正在为Angular应用程序采用Nrwl.io中的Nx框架。

作为其中的一部分,我们试图了解数据持久性模块中乐观更新和悲观更新方法之间的潜在实现差异。

根据文档,悲观主义更新将在客户端之前更新服务器,而乐观主义更新则会首先更新客户端。

然而,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方法成功完成时,用于调用乐观更新方法的示例代码不会分派操作。我的理解是,这将结束流——没有迹象表明后端调用应该返回什么。

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 to pipe,您需要提供它(这些是您在第一个代码块中找到的函数(。后者看起来像您的第二个代码块。

实现的乐观和悲观之间的区别只是有能力回滚乐观更新(由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
}))
);
}

最新更新