fetch API加延迟无效 触发429请求限流报错
问题原因
你之前添加的3秒延迟未生效的核心逻辑错误:Array.map 是同步执行的遍历方法,遍历所有id时会几乎同时注册所有3秒定时器,3秒计时结束后所有请求会并发发出,完全没有错开请求时间,自然还是会触发接口的每秒请求频率限制,返回429报错。
解决方法
1. 基础方案:串行请求+固定间隔(实现最简单,稳定性最高)
放弃全并发的Promise.all写法,改用for循环逐个发起请求,每个请求之间预留足够的间隔时间,保证任意1秒窗口内的请求数不超过接口限流阈值,同时增加429报错自动重试逻辑,兜底偶发的限流场景。
修正后代码如下:
export async function getThirdAPI(access_token, id_array, globalObject) { const results = []; // 可根据第三方接口实际限流阈值调整间隔时间,建议比限流要求的间隔多留100-200ms冗余,避免网络波动导致触发限流 const REQUEST_INTERVAL = 3000; const MAX_RETRY = 3; for (const id of id_array) { // 每个请求发起前等待固定间隔 await new Promise(resolve => setTimeout(resolve, REQUEST_INTERVAL)); let url = `${baseAPI}/participants/${id}`; const requestOption = { method: 'GET', headers: { authorization: `Bearer ${access_token}` } }; // 封装单请求逻辑,支持重试 let retryCount = 0; let data = null; while (retryCount <= MAX_RETRY) { const response = await fetch(url, requestOption); data = await response.json(); if (data.code !== 429) break; retryCount++; // 触发限流时额外等待后重试 await new Promise(resolve => setTimeout(resolve, REQUEST_INTERVAL)); } results.push(data); } console.log(results); globalObject.store_data.push(...results); return globalObject; }
2. 优化方案:可控并发请求(适合id数量较多,需要平衡速度和稳定性的场景)
如果串行请求速度太慢,可以实现固定并发数的调度逻辑,比如设置同时最多发起2个请求,每个请求之间保持1.5秒以上间隔,保证每秒总请求数不超过接口阈值,比纯串行速度更快,同时不会触发限流。
注意事项
- 提前确认第三方接口的限流规则:是针对access_token维度、还是IP维度的限流,根据规则调整请求间隔,不要卡着限流阈值设置间隔,预留10%-20%的冗余量避免网络延迟、计时偏差导致的限流。
- 不要在同步遍历(map/forEach)中给每个任务加固定延迟,这类写法所有延迟计时是并行的,无法错峰。
内容的提问来源于stack exchange,提问作者Winterella
相关产品推荐
相关产品推荐

