实现一个批量请求函数 multiRequest(urls, maxNum),要求如下:
- 要求最大并发数 maxNum
- 每当有一个请求返回,就留下一个空位,可以增加新的请求
- 所有请求完成后,结果按照 urls 里面的顺序依次打出。
实现思路:递归进行实现,最初发送请求次数为最大并发上限,等某个请求结果返回后递归进行调用run方法发送请求,并使用新数组存放返回的请求结果,当所有请求都执行过之后,不再进行请求,等所有结果返回后,执行resolve方法,代码如下:
function multiRequest(tasks, maxNum) {
const len = tasks.length;
// 创建新数组用于存放请求的返回结果
const result = new Array(len).fill(false);
// 请求执行次数
let count = 0;
return new Promise((resolve, reject) => {
// 当小于最大并发数时,执行请求
while(count < maxNum) {
run();
}
function run() {
let cur = count++;
tasks[cur]().then(res => {
result[cur] = res;
}).catch(err => {
result[cur] = err;
}).finally(() => {
// 某个请求结果返回后,判断是否需要执行新的请求
if(count < tasks.length) {
run();
} else if (!result.includes(false)) {
// 所有的请求执行完成
resolve(result);
}
})
}
});
}
以下示例模拟请求操作:
function task1() {
return new Promise(resolve => {
setTimeout(() => {
resolve("task1");
console.log("task1")
})
});
}
function task2() {
return new Promise(resolve => {
setTimeout(() => {
resolve("task2");
console.log("task2")
}, 1000);
});
}
function task3() {
return new Promise(resolve => {
setTimeout(() => {
resolve("task3");
console.log("task3")
}, 20);
});
}
function task4() {
return new Promise(resolve => {
setTimeout(() => {
resolve("task4");
console.log("task4")
}, 500);
});
}
const tasks = [task1, task2, task3, task4];
// 执行
multiRequest(tasks, 2).then(res => {console.log(res)});
执行结果如下: