Vue 项目中主从表异步保存实战:缓存导致接口不执行问题排查与解决
一、项目背景
在开发企业级管理系统时,常见的业务场景是多张主从表数据联合保存。比如一个“资金利息付款”功能,涉及:
主表:资金利息付款信息(如付款批次、总金额等)
从表1:付款明细列表(interestPaymentList)
从表2:付款退回明细列表(interestRefundList)
前端业务逻辑通常是:
先调用主表保存接口,返回主表 ID。
主表保存成功后,附加主表 ID 给从表数据。
并行调用两个从表保存接口。
最终统一处理保存成功/失败的结果。
二、核心代码示例
下面是本项目中保存主从表的核心函数 submiteParams
submiteParams(params) {if (this.action.type == 'update' && !this.action.isCopy) {params.entity.interestPaymentId = this.action.idparams.entity.batchId = this.action.batchId}if (this.action.relativeData && Object.keys(this.action.relativeData).length) {params = { ...params, ...this.action.relativeData }}pmInterestPaymentSaveAPI(params).then(res => {this.loading = falseconst interestPaymentId = res.data.interestPayment // 主表IDconst documentCode = res.data.documentCode || ''// 给付款从表加主表ID、单据编号const paymentInfoList = this.interestPaymentList.map(item => ({...item,interestPaymentId,documentCode}))// 给付款退回从表加主表ID、单据编号const refundInfoList = this.interestRefundList.map(item => ({...item,interestPaymentId,documentCode}))console.log('付款从表数据:', paymentInfoList)console.log('付款退回从表数据:', refundInfoList)// 并行保存两个从表return Promise.all([pmInterestPaymentInfoSaveListAPI(paymentInfoList),pmInterestPaymentRefundInfoSaveListAPI(refundInfoList)])}).then(() => {if (this.action.isCopy) {this.$message.success('操作成功')} else {this.$message.success(this.action.type == 'update' ? '编辑成功' : '添加成功')}this.close()this.$emit('save-success', { type: 'interestPayment' })}).catch(() => {this.loading = false})
}
三、遇到的问题
初期测试时,发现即便 interestRefundList
(付款退回从表)有数据,但对应的保存接口 pmInterestPaymentRefundInfoSaveListAPI
并没有被调用,网络请求里也找不到对应的接口调用。
而付款明细接口 pmInterestPaymentInfoSaveListAPI
正常执行并保存成功。
这种情况让人非常困惑,因为:
从表数据非空且正确;
代码结构正确,两个接口调用写在
Promise.all
中;逻辑应该同时执行。
四、问题分析与定位
经过调试和排查,结合打印日志与断点观察,发现:
打印日志不输出付款退回从表数据,怀疑异步函数未进入退回分支;
退出当前页面后重新进入,问题消失,两个接口都能正常调用;
进一步确认是浏览器或前端框架的缓存导致数据未刷新,旧数据导致退回列表为空或接口调用跳过;
通过强制刷新数据、清除缓存、保证每次保存时
interestRefundList
都是最新且有数据,问题解决。
五、解决方案及细节
1. 保证数据实时性
确保每次调用保存前,this.interestRefundList
是通过接口或用户操作最新赋值的,避免被旧缓存覆盖。
// 确保数据获取逻辑 fetchRefundList(orderNumber).then(data => {this.interestRefundList = data || [] })
2. 打印调试
保存函数内部,加入打印,观察数据:
console.log('付款从表数据:', paymentInfoList)
console.log('付款退回从表数据:', refundInfoList)
确保打印时数据不为空。
3. 使用 Promise.all 并行执行接口
Promise.all
传入的数组中,所有接口都要是有效的 Promise,且参数有效:
return Promise.all([ pmInterestPaymentInfoSaveListAPI(paymentInfoList), pmInterestPaymentRefundInfoSaveListAPI(refundInfoList) ])
如果某个参数为空数组或 null
,有些接口实现会直接跳过请求,需注意。
4. 清除缓存和刷新页面测试
前端开发中常见“代码修改没生效”的原因是浏览器缓存,特别是 Service Worker、HTTP 缓存、Vue 组件缓存等。遇到接口未执行问题,可以尝试:
退出登录重新登录;
刷新页面,清除浏览器缓存(Ctrl+F5);
关闭再打开页面;
检查开发工具 Network 面板是否真的发送请求。
六、代码优化建议
保存前判断从表数据是否为空,避免空数组调用接口:
const promises = []
if (paymentInfoList.length > 0) {
promises.push(pmInterestPaymentInfoSaveListAPI(paymentInfoList))
}
if (refundInfoList.length > 0) {
promises.push(pmInterestPaymentRefundInfoSaveListAPI(refundInfoList))
}
return Promise.all(promises)
细化错误捕获,分别提示不同接口错误;
添加加载状态控制,防止重复提交。
七、总结
主从表数据保存,推荐先保存主表拿到 ID,再给从表数据附加主表 ID,最后并行调用保存接口。
Promise.all
可以并行等待多个接口,避免回调地狱。遇到接口未调用,第一步检查数据是否为空,第二步检查参数格式,第三步排查缓存问题。
使用浏览器调试工具 Network 面板、Console 打印日志,逐步定位问题。
缓存问题常见于开发环境,重启、刷新、清缓存往往能解决。