前端多文件上传队列异常问题:批量上传时仍同时发送所有文件至服务器
前端多文件上传队列异常问题:批量上传时仍同时发送所有文件至服务器
看起来你已经尝试用递归的方式实现串行上传,但还是遇到了所有文件同时发送的问题,导致服务器崩溃。我来帮你分析下可能的原因,以及给出可行的修复方案。
可能的问题点
- 未处理请求错误导致队列异常:如果某个文件上传请求抛出错误但没被捕获,可能会打断正常的递归逻辑,甚至触发浏览器的异常处理机制,意外并发发送剩余请求。
- 重复的状态更新逻辑:你的
uploadFilesArray函数里已经完成了加载状态关闭和数据刷新,但外层uploadFile函数又重复调用了这些操作,容易造成状态混乱,甚至触发重复上传。 - FileList对象的遍历隐患:如果传入的
files是原生FileList对象(而非普通数组),虽然能通过索引访问,但部分场景下会出现遍历异常,导致递归逻辑不符合预期。
修复后的代码示例
1. 优化串行上传队列,添加错误处理
const uploadFilesArray = async (files, id) => { const uploadFileAtIndex = async (index) => { // 所有文件上传完成,更新状态并刷新数据 if (index >= files.length) { setLoading(false); reloadData(id); return; } const file = files[index]; const formData = new FormData(); formData.append("file", file); try { // 等待当前文件上传完成,确保串行执行 await axios.post(`/app/orderfile/${id}`, formData, { // 可选:添加上传进度监听,提升用户体验 onUploadProgress: (progressEvent) => { const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total); console.log(`第 ${index+1}/${files.length} 个文件:${percent}%`); } }); // 当前文件上传成功,继续下一个 await uploadFileAtIndex(index + 1); } catch (error) { console.error(`第 ${index+1} 个文件上传失败:`, error); // 这里可以根据需求选择重试或跳过失败文件 // 示例:跳过失败文件,继续上传下一个 await uploadFileAtIndex(index + 1); } }; await uploadFileAtIndex(0); };
2. 简化外层触发逻辑,避免重复状态操作
const uploadFile = (files) => { // 把FileList转为数组,避免原生对象的遍历问题 const fileArray = Array.from(files); if (fileArray.length === 0) return; setLoading(true); if (!info || !info.id) { createOrder() .then(({ id }) => { if (id) { uploadFilesArray(fileArray, id); } else { setLoading(false); console.error("创建订单失败,无法上传文件"); } }) .catch((error) => { setLoading(false); console.error("创建订单出错:", error); }); } else { uploadFilesArray(fileArray, info.id); } };
关键优化说明
- 强制串行执行:通过
await确保每个axios请求完全完成(成功或失败)后,再发起下一个文件的上传请求,彻底避免并发上传。 - 错误捕获与处理:用
try-catch包裹请求逻辑,即使某个文件上传失败,也不会中断整个上传队列,同时可以根据业务需求添加重试逻辑。 - FileList转数组:将原生的FileList对象转为普通数组,避免因FileList的只读特性导致的遍历异常。
- 移除重复状态更新:只在
uploadFilesArray的递归结束时更新加载状态和刷新数据,避免逻辑冲突。
备注:内容来源于stack exchange,提问作者Moh3n.As
相关产品推荐
相关产品推荐

