批量请求函数
使用 Promise 实现一个异步流量控制的函数, 比如一共 10 个请求, 每个请求的快慢不同, 最多同时 3 个请求发出, 快的一个请求返回后, 就从剩下的 7 个请求里再找一个放进请求池里, 如此循环:
async function asyncFlowControl (requests, maxConcurrent) {
const results = [];
const executing = []; // 当前正在执行的 Promise
for (let i = 0; i < requests.length; i++) {
const request = requests[i];
// 创建一个包装 Promise:执行请求 + 记录结果 + 从 executing 中移除自身
const promise = fakeAsyncRequest(request).then(result => {
results[i] = result; // 保持顺序
return result;
}).finally(() => {
// 从 executing 中移除已完成的 Promise
const index = executing.indexOf(promise);
if (index !== -1) executing.splice(index, 1);
});
executing.push(promise);
// 如果当前并发数达到上限,就等其中一个完成
if (executing.length >= maxConcurrent) {
await Promise.race(executing); // 等最快完成的那个
}
}
// 等所有剩余请求完成
await Promise.all(executing);
return results;
}
// 模拟异步请求的函数,返回一个 Promise
function fakeAsyncRequest(request) {
return new Promise(resolve => {
const delay = Math.floor(Math.random() * 100); // 模拟不同请求的处理时间
setTimeout(() => {
console.log(`请求 ${request} 耗时 ${delay} 完成`);
resolve(`请求 ${request} 结果`);
}, delay);
});
}
// 创建10个请求
const requests = Array.from({ length: 10 }, (_, i) => i + 1);
// 控制最多同时3个请求
asyncFlowControl(requests, 3)
.then(results => {
console.log('所有请求已完成');
console.log(results);
})
.catch(error => {
console.error('发生错误:', error);
});