let urls = ['bytedance.com','tencent.com','alibaba.com','microsoft.com','apple.com','hulu.com','amazon.com'] // 请求地址
let pool = []//并发池
let dataArr=[]
let max = 3 //最大并发量
//自定义请求函数
var request = url => {
return new Promise(resolve => {
setTimeout(() => {
resolve(`任务${url}完成`)
}, 1000)
// }, 1000*Math.floor(Math.random()*5+1))
})
}
// 方法一
// //先循环把并发池塞满
while (pool.length <= max) {
let url = urls.shift();
addTask(url)
}
//添加任务
function addTask(url){
let task = request(url);
pool.push(task);
task.then(res => {
//请求结束后将该Promise任务从并发池中移除
dataArr.push({
url,
res,
})
console.log('外部逻辑', res);
pool.splice(pool.indexOf(task), 1);
console.log(`${url} 结束,当前并发数:${pool.length}`);
url = urls.shift();
// //每当并发池跑完一个任务,就再塞入一个任务
if(url !== undefined){
addTask(url);
}
else if(!pool.length){
console.log(dataArr)
}
})
}
/**方法二
* @description 控制promise.all并发数量
* @param limit 并发数
* @param array 参数列表
* @param request 执行函数
* @returns {Promise<Awaited<unknown>[]>}
*/
async function promiseAllLimit(limit, array, apiFn) {
const ret = [] // 用于存放所有的promise实例
const executing = [] // 用于存放目前正在执行的promise
for (const item of array) {
const p = apiFn(item)
ret.push(p)
console.log(limit <= array.length,limit,array.length)
if (limit <= array.length) {
// then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除
const e = p.then(() => executing.splice(executing.indexOf(e), 1))
executing.push(e)
if (executing.length >= limit) {
// 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更,
// 状态变更后,就会执行上面then的回调,将该promise从executing中删除,
// 然后再进入到下一次for循环,生成新的promise进行补充
await Promise.race(executing)
}
}
}
return Promise.all(ret)
}
// promiseAllLimit(3, urls, request).then((res) => {
// console.log('Promise.all 结果',res)
// })
// 方法3
function run(max){
//启动函数,直接将max个请求进行执行
for (let i=0;i<max;i++){
let url =urls.shift()
console.log(url,'url')
send(url,request(url));
}
}
function send(url,promise){
pool.push(promise);
promise.then((res)=>{
// dataArr.push({
// url,
// res,
// })
console.log(`id${res}的请求已经处理完毕,当前并发${pool.length}`);
//移除已处理的请求
pool.splice(pool.indexOf(promise),1);
let id = urls.shift();
console.log(id,11)
if (id !==undefined){
send(request(id));
}
// else{
// console.log(dataArr)
// }
})
}
// run(3);
console