JS实现for循环每调用数次API后等待固定时长直至数组遍历完成
代码问题说明
interval函数未返回Promise,await interval()不会等待100ms延时结束就会直接执行后续循环,完全没有限流暂停的效果- 循环条件错误:
for (let i = 0; i <= arr.length; i++)会超出数组下标范围,数组最大下标是arr.length-1,最后一次循环会拿到undefined元素 - 计数逻辑冗余且错误:使用全局的
breakCounter+arr.indexOf计算暂停时机的逻辑混乱,既存在全局变量污染问题,也无法准确命中每2次请求后暂停的触发条件 - 非暂停分支的
makeAPI直接同步调用,所有非暂停的请求会瞬间并发发出,完全没有控制请求频率的效果 - 暂停分支的当前元素请求放在
setTimeout中执行,会导致该元素的请求比后续元素的请求更晚触发,出现执行顺序错乱
修复后代码
串行执行版本(请求按顺序逐个发起,每2个请求后暂停100ms)
const arr = ["val1", "val2", "val3", "val4", "val5", "val6"]; const REQUESTS_PER_BATCH = 2; // 每批次请求数量,可调整为2-3 const WAIT_TIME = 100; // 批次间等待时间,单位ms async function seriesAPI(arr) { for (let i = 0; i < arr.length; i++) { // 发起当前请求 await makeAPI(arr[i]); // 每处理完REQUESTS_PER_BATCH个请求,且不是最后一个元素时,暂停等待 if ((i + 1) % REQUESTS_PER_BATCH === 0 && i !== arr.length - 1) { console.log("Buffer time"); await wait(WAIT_TIME); } } } // 封装延时函数,返回Promise供await调用 function wait(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function makeAPI(val) { console.log(val); // 实际请求可放开下方注释,返回fetch的Promise保证等待请求完成 // return fetch(url, {method: 'POST', body: JSON.stringify(val)}).then(res => console.log(res)); } seriesAPI(arr);
同批次并发版本(每批次2个请求并发发送,批次间暂停100ms,性能更高)
const arr = ["val1", "val2", "val3", "val4", "val5", "val6"]; const REQUESTS_PER_BATCH = 2; // 每批次请求数量,可调整为2-3 const WAIT_TIME = 100; // 批次间等待时间,单位ms async function seriesAPI(arr) { const batches = []; // 按每REQUESTS_PER_BATCH个元素分一组 for (let i = 0; i < arr.length; i += REQUESTS_PER_BATCH) { batches.push(arr.slice(i, i + REQUESTS_PER_BATCH)); } for (let i = 0; i < batches.length; i++) { const batch = batches[i]; // 同批次请求并发发送 await Promise.all(batch.map(item => makeAPI(item))); // 不是最后一批的话等待100ms if (i !== batches.length - 1) { console.log("Buffer time"); await wait(WAIT_TIME); } } } // 封装延时函数,返回Promise供await调用 function wait(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function makeAPI(val) { console.log(val); // 实际请求可放开下方注释,返回fetch的Promise保证等待请求完成 // return fetch(url, {method: 'POST', body: JSON.stringify(val)}).then(res => console.log(res)); } seriesAPI(arr);
内容的提问来源于stack exchange,提问作者sabarinath
相关产品推荐
相关产品推荐

