如何限制for循环最多执行50次以适配API调用频次限制?
解决API调用限制的循环改造方案
问题说明
数据库每日新增约200条记录,原逻辑是每日7点调用200次API获取数据,但现在API新增每小时最多50次调用的限制,超量会被封禁24小时。需要改造原for...of循环,要求:
- 每次运行最多执行50次迭代
- 不能破坏
${record.name}的URL拼接逻辑 - 最终必须遍历完所有记录
原代码片段:
for (let record of records ) { //This loop has to be limited to 50 iterations pr run. let brregRawData = await fetch(`some url/${record.name}/someurl`); let brregJson = await brregRawData.json() let personNavn = brregJson.rollegrupper[0].roller[0].person.navn.fornavn let personEtternavn = brregJson.rollegrupper[0].roller[0].person.navn.etternavn // if mellomnavn = undefined, then do nothing if (brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn == undefined) { var personMellomNavn = ""; } else { let personMellomNavn = brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn + " "; } }
可行解决方案
方案一:自动分批+定时等待(一次性启动,自动完成所有处理)
把所有记录按每50条拆分批次,处理完一批后等待1小时再处理下一批,完全保留原URL拼接逻辑:
// 配置每批处理数量和间隔时间(1小时=3600000毫秒) const BATCH_SIZE = 50; const WAIT_TIME = 3600000; async function processRecordsInBatches(records) { // 循环拆分批次 for (let i = 0; i < records.length; i += BATCH_SIZE) { const currentBatch = records.slice(i, i + BATCH_SIZE); // 处理当前批次的50条记录,原逻辑完全保留 for (let record of currentBatch) { try { let brregRawData = await fetch(`some url/${record.name}/someurl`); let brregJson = await brregRawData.json(); let personNavn = brregJson.rollegrupper[0].roller[0].person.navn.fornavn; let personEtternavn = brregJson.rollegrupper[0].roller[0].person.navn.etternavn; // 简化原判断逻辑,避免var/let混用的作用域问题 let personMellomNavn = brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn ? brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn + " " : ""; // 这里添加后续的数据库更新或其他业务逻辑 } catch (err) { console.error(`处理记录 ${record.name} 出错:`, err); // 可选:记录失败的记录,后续手动重试 } } // 如果不是最后一批,等待1小时再继续 if (i + BATCH_SIZE < records.length) { console.log(`已处理${i + BATCH_SIZE}条记录,等待1小时后继续...`); await new Promise(resolve => setTimeout(resolve, WAIT_TIME)); } } console.log("所有记录处理完成"); } // 启动处理 processRecordsInBatches(records);
方案二:分时段触发(借助定时任务工具)
如果不想让程序一直挂着等待,可以把200条记录分成4个批次,用系统定时任务(比如Linux的cron、Windows任务计划)分别在7点、8点、9点、10点触发处理:
// 接收批次索引(0-3),处理对应批次的50条记录 async function processSingleBatch(records, batchIndex) { const BATCH_SIZE = 50; const start = batchIndex * BATCH_SIZE; const end = start + BATCH_SIZE; const targetBatch = records.slice(start, end); for (let record of targetBatch) { // 原逻辑丝毫不改,URL拼接完全不受影响 let brregRawData = await fetch(`some url/${record.name}/someurl`); let brregJson = await brregRawData.json(); let personNavn = brregJson.rollegrupper[0].roller[0].person.navn.fornavn; let personEtternavn = brregJson.rollegrupper[0].roller[0].person.navn.etternavn; let personMellomNavn = brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn ? brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn + " " : ""; // 后续业务逻辑 } } // 示例调用:7点执行 processSingleBatch(records, 0),8点执行processSingleBatch(records,1),以此类推
两种方案都不会破坏${record.name}的URL拼接,完全符合API调用限制要求,能遍历完所有记录。
内容的提问来源于stack exchange,提问作者Ruben Rossvold
相关产品推荐
相关产品推荐

