React中批量上传音频:控制同时仅发送3个POST请求
分批音频文件上传实现方案
核心逻辑
- 将已选中的音频文件数组按每3个为一组拆分
- 依次处理每组:每组内同时发起3个POST请求,等待该组所有请求完成(无论成功或失败)后,再启动下一组请求
- 使用
Promise.allSettled()确保等待组内所有请求结束,避免因单个请求失败中断整个上传流程
完整代码实现
假设你使用React进行状态管理,以下是完整的上传逻辑实现:
import axios from 'axios'; import { useState } from 'react'; function AudioUploader() { const [selectedFiles, setSelectedFiles] = useState([]); // 处理文件选择(你已有的逻辑) const handleFileChange = (e) => { setSelectedFiles(Array.from(e.target.files)); }; // 将数组拆分为指定大小的批次 const splitIntoBatches = (array, batchSize) => { const batches = []; for (let i = 0; i < array.length; i += batchSize) { batches.push(array.slice(i, i + batchSize)); } return batches; }; // 单个文件上传函数 const uploadFile = async (file) => { const formData = new FormData(); formData.append('file', file); try { const response = await axios.post('/your-upload-endpoint', formData, { headers: { 'Content-Type': 'multipart/form-data', }, // 可选:添加上传进度监听 onUploadProgress: (progressEvent) => { const percentCompleted = Math.round( (progressEvent.loaded * 100) / progressEvent.total ); console.log(`${file.name} 上传进度:${percentCompleted}%`); }, }); return { success: true, file: file.name, data: response.data }; } catch (error) { return { success: false, file: file.name, error: error.message }; } }; // 批量上传主函数 const handleBatchUpload = async () => { if (selectedFiles.length === 0) return; // 拆分为每3个一组 const batches = splitIntoBatches(selectedFiles, 3); // 依次处理每个批次 for (const batch of batches) { console.log(`开始处理批次:${batch.map(f => f.name).join(', ')}`); // 发起组内所有请求,等待全部完成 const results = await Promise.allSettled(batch.map(uploadFile)); // 处理当前批次的结果(可选) results.forEach(result => { if (result.status === 'fulfilled') { const res = result.value; if (res.success) { console.log(`${res.file} 上传成功`, res.data); } else { console.error(`${res.file} 上传失败`, res.error); } } else { console.error(`${result.reason.file} 上传异常`, result.reason); } }); console.log('当前批次处理完成,开始下一批次'); } console.log('所有文件上传流程结束'); }; return ( <div> <input type="file" multiple name="file" className="myform" onChange={handleFileChange} accept="audio/wav" /> <button onClick={handleBatchUpload} disabled={selectedFiles.length === 0}> UPLOAD </button> </div> ); } export default AudioUploader;
关键细节说明
splitIntoBatches:通用的数组分批工具函数,可根据需要调整批次大小(当前为3)Promise.allSettled():与Promise.all()不同,它会等待所有Promise完成(无论resolve或reject),确保批次内所有请求都处理完毕再进入下一批FormData:上传文件必须使用该对象封装,确保请求符合multipart/form-data格式- 上传进度监听:可选功能,可根据需求添加UI进度展示
内容的提问来源于stack exchange,提问作者MD ALI
相关产品推荐
相关产品推荐

