这道题比较有意思,其实就是要实现一个限制最大并发的 Promise.all()。
实现思路也比较简单,就是在每个请求结束后,看队列中是否有未完成的请求,如果有,就按顺序进行下一个请求。
function multiRequest(urls = [], maxNum) {
// 请求总数量
const sum = urls.length;
// 根据请求数量创建一个数组来保存请求的结果
const result = new Array(sum).fill(false);
// 当前完成的数量
let count = 0;
return new Promise((resolve, reject) => {
// 请求maxNum个
while (count < maxNum) {
next();
}
function next() {
let current = count++;
// 处理边界条件
if (current >= sum) {
// 请求全部完成就将promise置为成功状态, 然后将result作为promise值返回
!result.includes(false) && resolve(result);
return;
}
const url = urls[current];
console.log(`开始 ${current}`, new Date().toLocaleString());
fetch(url)
.then((res) => {
// 保存请求结果
result[current] = res;
console.log(`完成 ${current}`, new Date().toLocaleString());
// 请求没有全部完成, 就递归
if (current < sum) {
next();
}
})
.catch((err) => {
console.log(`结束 ${current}`, new Date().toLocaleString());
result[current] = err;
// 请求没有全部完成, 就递归
if (current < sum) {
next();
}
});
}
});
}
const url = `https://www.baidu.com/s?wd=javascript`;
const urls = new Array(100).fill(url);
(async () => {
const res = await multiRequest(urls, 10);
console.log(res);
})();