使用Promise循环执行Ajax处理大数据出现资源不足及504错误如何解决
问题原因
你当前的代码会一次性发起所有列表条目对应的AJAX请求,列表体量极大的情况下会触发两层异常:
- 浏览器端瞬间发起上百甚至上千个并发请求,超过浏览器资源负载限制,触发
net::ERR_INSUFFICIENT_RESOURCES错误 - 服务器端瞬间接收海量请求,PHP进程被占满、单请求处理超时,返回504网关超时错误
修复方案
1. 前端增加并发请求限流,禁止一次性发起所有请求
推荐采用固定并发数的分批处理方案,比如一次同时处理3~5个请求,一批处理完成后再发起下一批,参考代码如下:
async function syncCgiu(form_data, response) { // 单次并发数,可根据服务器承载能力调整,一般3~10为合理区间 const concurrency = 3; const list = response.content; let currentIndex = 0; // 单条条目处理逻辑 async function processItem() { if (currentIndex >= list.length) return; const value = list[currentIndex++]; // 注意对参数做转义,避免特殊字符导致请求异常 const data = `${form_data}&action=sync_cgiu&lookup=${encodeURIComponent(value)}`; try { await $.post(ajaxurl, data); console.log(value + ' imported'); } catch (err) { // 可在此处添加失败重试、失败条目记录逻辑 console.error(value + ' import failed', err); } // 处理完当前条目后自动接手下一条 return processItem(); } // 启动指定数量的并发处理进程 const workers = Array(concurrency).fill().map(() => processItem()); // 等待所有条目处理完成 await Promise.all(workers); console.log('finish import'); }
2. PHP侧适配优化
- 对应
sync_cgiu接口的处理逻辑开头添加set_time_limit(30),放开单条请求的最大执行时间限制,避免单条数据处理时间稍长就触发PHP超时 - 如果单条数据处理逻辑仍较重,可以将请求内容先存入消息队列,用后台CLI进程异步处理,接口直接返回处理中状态,前端通过轮询查询整体处理进度
3. 额外优化建议
- 可添加失败重试逻辑,对单次请求失败的条目自动重试1~2次,提升整体导入成功率
- 可增加进度展示逻辑,实时告知用户当前导入进度,避免用户误判页面卡住
内容的提问来源于stack exchange,提问作者marcelo2605
相关产品推荐
相关产品推荐

