如何在JavaScript中设置请求间隔?React+Axios API限流方案
解决API请求频率限制:每秒最多3次POST请求的实现
你当前的代码问题在于,arrayLeadId.map里的异步函数会被同时触发,await只在单个函数内部生效,map本身不会等待前一个请求完成再发下一个,导致所有请求几乎同时打向API,超出了每秒3次的限制。下面给你两种简单易懂的解决方案:
方案一:逐个请求+固定间隔(新手友好)
用for...of循环替代map,循环会等待每个请求完成后,再延迟一段时间发起下一个请求,保证每秒最多3次(间隔约333ms,1000ms/3≈333)。
// 先定义一个延迟工具函数 const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); // 封装处理所有请求的异步函数 async function processAllLeads() { for (const leadId of arrayLeadId) { // 格式化数据 const formattedData = formatData(leadId, finalPipeline, finalStatus, user, tag); try { // 发起请求并等待结果 const resp = await pipelineServices.updateLeads(formattedData, token); console.log(resp); } catch (error) { // 处理单个请求的错误,避免影响后续请求 console.error(`处理leadId ${leadId}时出错:`, error); } // 每次请求后延迟333ms,控制频率 await delay(333); } } // 调用函数开始处理 processAllLeads();
方案二:分批次请求(效率更高)
如果想提升效率,可以把请求分成每3个一组,同一批次的3个请求同时发起,然后等待1秒再发下一批,这样既符合API限制,又能更快完成所有请求。
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); async function processLeadsInBatches() { const batchSize = 3; // 每批3个请求 const totalLeads = arrayLeadId.length; for (let i = 0; i < totalLeads; i += batchSize) { // 截取当前批次的leadId const currentBatch = arrayLeadId.slice(i, i + batchSize); // 并行发起当前批次的所有请求 const batchRequests = currentBatch.map(async leadId => { const formattedData = formatData(leadId, finalPipeline, finalStatus, user, tag); try { const resp = await pipelineServices.updateLeads(formattedData, token); console.log(resp); } catch (error) { console.error(`处理leadId ${leadId}时出错:`, error); } }); // 等待当前批次所有请求完成 await Promise.all(batchRequests); // 如果不是最后一批,等待1秒再处理下一批 if (i + batchSize < totalLeads) { await delay(1000); } } } // 调用函数开始处理 processLeadsInBatches();
关键注意点
- 不要用
map处理异步请求:map会一次性创建所有异步任务并执行,无法控制执行顺序和间隔。 - 错误处理:用
try/catch包裹每个请求,避免单个请求失败导致整个流程中断。 - 间隔调整:如果API限制严格,可以把333ms改成350ms,或者把批次间隔改成1100ms,留一点缓冲时间,避免因网络波动导致超限制。
内容的提问来源于stack exchange,提问作者Motias
相关产品推荐
相关产品推荐

