如何在Ngrx Effects乐观流程中提前触发成功动作?
关于Ngrx Effects乐观工作流的实现方案
嘿,这个场景太常见了!要在后端请求完成前触发成功动作(也就是乐观更新),核心思路是把数据流拆成两部分:立即发送成功动作更新本地状态,同时并行处理后端API请求,后续根据API结果决定是否回滚状态。
直接给你修改后的代码,我会逐行解释:
@Effect() save$ = this.actions$ .ofType(myActions.SAVE) .map((action: myActions.SaveAction) => action.payload) .mergeMap((foo) => { // 1. 立即生成并发出成功动作,这一步会直接更新本地状态(乐观更新) const optimisticSuccess = new myActions.SaveSuccessAction(foo); // 2. 处理后端API请求,失败时返回失败动作 const apiRequest$ = this.myService.updateFoo(foo) .catch(error => Observable.of(new myActions.SaveFailAction(error))); // 3. 合并两个流:先发出乐观成功动作,再处理API响应 return Observable.concat( Observable.of(optimisticSuccess), apiRequest$ ); });
关键细节说明:
- 用
mergeMap替代switchMap:switchMap会取消之前未完成的请求,而我们需要同时处理“乐观更新”和“API请求”两个流,mergeMap允许并行处理这些流。 Observable.concat的作用:确保乐观成功动作先被发出,之后再处理API的响应结果——如果API请求失败,SaveFailAction会被触发,这时候你需要在reducer里做状态回滚,把之前乐观更新的内容还原回去,避免本地状态和后端数据不一致。- 必须处理失败回滚:这是乐观更新的核心注意点!比如用户提交了一个修改,你先更新了本地UI,结果后端报错了,一定要把UI改回原来的状态,不然用户会以为操作成功了。
举个reducer里回滚的简单例子:
case myActions.SAVE_FAIL: // 假设你之前用乐观更新修改了某个foo,这里根据失败动作里的信息还原 return { ...state, foos: state.foos.map(foo => foo.id === action.payload.id ? action.payload.originalFoo : foo ) };
内容的提问来源于stack exchange,提问作者Rachid O
相关产品推荐
相关产品推荐

