如何在上一个HTTP请求完成前阻止发送新的HTTP请求
问题解决方案
核心思路是给请求添加状态锁,判断当前是否有正在进行中的请求,只有无待处理请求时才触发新请求,从根源避免请求并行导致的返回顺序错乱问题。
步骤1:新增请求锁状态
在组件初始化的state中新增请求状态标记:
// 组件state初始化部分新增字段 this.state = { // 原有其他state配置 isRequesting: false // 请求锁标识,true表示存在进行中的请求,禁止发起新请求 }
步骤2:改造事件处理函数,增加锁逻辑
修改parentAccHandler函数,进入时先校验锁状态,请求发起时上锁,请求完成(无论成功/失败)均解锁:
const parallel = (...Promises) => { return Promise.all(Promises); }; export function parentAccHandler(e, inputFiled) { // 存在进行中的请求直接返回,不发起新请求 if (this.state.isRequesting) return; const parentAccValue = e.target.value; const { fields } = this.state; // 发起请求前先上锁 this.setState({ isRequesting: true }); parallel( getUsedRecord(fields), axios.get(`chartofaccounts/nextPK/${parentAccValue}`) ) .then(([usedRecord, nextPkRes]) => { this.setState((state, props) => { const { fields } = state; fields.acc_no.value = nextPkRes.data.next_PK ? nextPkRes.data.next_PK : ""; return { fields: updateOnParentAcc.call(this, fields, usedRecord, "PRESENT"), isRequesting: false // 请求成功,解锁 }; }); }) .catch((err) => { this.setState((state, props) => { let { fields } = state; fields.acc_no.value = ""; fields.parent_acc.prevReqStatus = "FULFILLED"; if (parseInt(parentAccValue) === 0) { fields = updateOnParentAcc.call(this, fields, null, "ZERO"); } else { fields = updateOnParentAcc.call(this, fields); } return { fields: fields, isRequesting: false // 请求失败必须解锁,避免后续请求被永久阻塞 }; }); }); }
可选优化:增加防抖逻辑
如果需要进一步降低请求频率,可在锁逻辑的基础上叠加300~500ms的防抖处理,用户连续输入结束后才触发请求,进一步降低服务端压力。
内容的提问来源于stack exchange,提问作者Karim shousha
相关产品推荐
相关产品推荐

