NodeJS处理API速率限制 实现按秒分批次请求的方法
Yelp API 限流下批量详情查询实现方案
针对固定QPS阈值的API调用场景,采用分块并行+窗口间隔的调度逻辑即可,既比串行遍历速度快,又不会触发速率限制,预设的每秒5次请求比预估的10QPS阈值留了50%冗余,稳定性足够。
核心实现逻辑
- 将所有待查询的商家ID按固定批次大小拆分,单批次内请求并行发起,最大化利用每秒的请求配额
- 记录单批次请求的实际耗时,补足等待时间到1秒后再发起下一批,避免死板固定等待浪费时间
- 增加错误捕获,避免单请求失败中断整个批量拉取流程
可直接复用的代码实现
首先引入通用等待工具函数:
// 延迟工具函数 const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
替换原有遍历拉取详情的逻辑即可:
// 限流配置,可根据实际接口阈值调整 const REQUEST_PER_SECOND = 5; const RATE_LIMIT_WINDOW = 1000; // 单位:毫秒 const businesses = response.body.businesses; const allBusinessDetails = []; for (let i = 0; i < businesses.length; i += REQUEST_PER_SECOND) { // 截取当前批次要处理的商家 const currentBatch = businesses.slice(i, i + REQUEST_PER_SECOND); const batchStartTimestamp = Date.now(); try { // 批次内并行发起所有详情请求 const batchResults = await Promise.all( currentBatch.map(item => fetchPlaceDetails(item.id)) ); allBusinessDetails.push(...batchResults); } catch (error) { // 可按需扩展单请求重试、失败记录逻辑 console.error(`批次${Math.floor(i / REQUEST_PER_SECOND) + 1}执行异常:`, error); } // 计算剩余等待时间,保证两次批次发起间隔不小于1秒 const elapsedTime = Date.now() - batchStartTimestamp; const needWait = Math.max(0, RATE_LIMIT_WINDOW - elapsedTime); if (needWait > 0) { await sleep(needWait); } } // 全量处理完成后可直接使用allBusinessDetails做后续逻辑
可选优化项
- 如果后续实测接口QPS阈值更高,直接修改
REQUEST_PER_SECOND参数即可,建议留20%以上的冗余避免偶发429错误 - 可扩展429状态码专属处理:如果接口返回限流错误,自动延长等待时间并重试当前批次,适配官方未明确标注阈值的场景
- 若单批次内个别请求响应极慢,可给
fetchPlaceDetails加超时控制,避免慢请求拖慢整个批次节奏
内容的提问来源于stack exchange,提问作者nickcoding2
相关产品推荐
相关产品推荐

