实现一个并发请求函数concurrencyrequest(urls, maxNum),要求如下:
要求最大并发数 maxNum 每当有一个请求返回,就留下一个空位,可以增加新的请求 所有请求完成后,结果按照 urls 里面的顺序依次打出(发送请求的函数可以直接使用fetch即可)
async function concurrencyRequest(urls, maxNum) {
const results = []; // 存放请求结果的数组
const executing = []; // 存放正在执行的请求的数组
let i = 0;
while (i < urls.length) {
// 控制最大并发数
while (executing.length < maxNum && i < urls.length) {
const url = urls[i++];
const requestPromise = fetch(url);
const index = executing.push(requestPromise) - 1;
// 异步请求完成后将Promise从executing数组中删除
requestPromise.then((result) => {
results[index] = result;
executing.splice(index, 1);
}).catch((error) => {
console.error(error);
executing.splice(index, 1);
});
}
// 等待有空闲请求的Promise完成
await Promise.race(executing);
}
return results;
}
该函数接收一个包含所有要发送请求的URL的数组和最大并发数作为参数。在函数内部,使用一个空数组 results
存放请求结果,使用另一个数组 executing
存放正在执行的请求,使用一个变量 i
记录已经发送了多少个请求。
函数使用一个while循环来控制并发请求的最大数量,并且在每次空闲的时候增加新的请求。在循环中,我们使用 fetch 发送异步请求,然后将 Promise 对象推入到 executing
数组中,并在异步请求完成时从该数组中删除该 Promise 对象。
在每次循环后,我们使用 Promise.race()
等待正在执行的请求中的任意一个完成,并将该请求从 executing
数组中删除。最后,当所有请求都完成后,将 results
数组返回。
使用示例:
const urls = [
'https://api.example.com/data/1',
'https://api.example.com/data/2',
'https://api.example.com/data/3',
'https://api.example.com/data/4',
'https://api.example.com/data/5',
'https://api.example.com/data/6',
'https://api.example.com/data/7',
'https://api.example.com/data/8',
'https://api.example.com/data/9',
'https://api.example.com/data/10',
'https://api.example.com/data/11',
'https://api.example.com/data/12',
'https://api.example.com/data/13',
'https://api.example.com/data/14',
'https://api.example.com/data/15',
'https://api.example.com/data/16',
'https://api.example.com/data/17',
'https://api.example.com/data/18',
'https://api.example.com/data/19',
'https://api.example.com/data/20'
];
concurrencyRequest(urls, 6).then((results) => {
console.log(results);
}).catch((error) => {
console.error(error);
});