RxJs中能否连续使用多个mergeMap?setCallHistory触发后数据未持久化
问题根因
首先你的连续mergeMap写法语法没有报错,但逻辑流程完全不符合预期,这是导致setCallHistory未生效的核心原因:
- 你第一个
mergeMap返回的是of(deleteCallHistory(res)),下游mergeMap接收到的入参是你刚刚创建的deleteCallHistory动作对象本身,而不是你预想的「删除处理后的通话列表」。Redux reducer处理动作后生成的新状态不会自动流回当前的RxJS流中,因此你传给setCallHistory的res.param本质是动作对象的属性,根本不是更新后的列表数据,自然无法正确存储。 - 你当前的代码中完全没有用到
withLatestFrom取到的state$,而删除指定项必然需要拿到待删除的记录标识,你大概率是把删除逻辑放在了Redux reducer中处理,但这个处理结果无法被当前流获取到。
修复方案
你不需要更换操作符,mergeMap完全适用于当前场景,只需要调整流内的处理逻辑:把删除计算逻辑直接放到流中执行,得到更新后的列表后再一次性派发所需动作即可,参考代码如下:
action$.pipe( ofType(DELETE_CALL_HISTORY), withLatestFrom(state$), mergeMap(([deleteAction, currentState]) => { // 从删除动作的payload中取到要删除的记录ID,按你实际的动作结构调整 const targetDeleteId = deleteAction.payload.id; return fromPromise(accessService.getCallHistory()).pipe( mergeMap((originCallList: any) => { // 流内直接计算得到删除后的新列表 const updatedList = originCallList.filter(item => item.id !== targetDeleteId); // 同时派发两个动作,不需要嵌套多层mergeMap return of( deleteCallHistory(updatedList), setCallHistory(updatedList) ); }), catchError((err: any) => { console.error(err); return of( showErrorAndHideAfterDelay({ message: err, label: 'Error', }), ); }), ); }), ),
额外检查项
如果修改后刷新页面数据依然恢复,需要检查两个点:
- 你的
setCallHistory动作对应的持久化逻辑(后端接口调用/本地存储写入)是否正常执行,有没有报错 - 页面初始化时拉取通话记录的逻辑是否正确读取了你持久化之后的最新数据
内容的提问来源于stack exchange,提问作者Tanmoy Sarker
相关产品推荐
相关产品推荐

