并发请求限制,n个请求,每次最多只能同时存在limit个请求,剩余的在队列中等待。
promiseAll 实现并发请求,n个请求,每次最多同时请求limit个,所有请求完成后处理数据。
思路: 定义一个请求池,run 函数每次将等待队列中任务加入到请求池中,直到塞满或等待队列空。再每个task执行完成后通过finally继续执行run函数,addTask 为往等待队列中添加任务,并执行run。
var startTime =new Date().getTime()
function taskPool(){
this.tasks = [];
this.pool = [];
this.max = 2;
}
taskPool.prototype.addTask = function(task){
this.tasks.push(task);
this.run();
}
taskPool.prototype.run = function(){
if(this.tasks.length ===0) return;
let min = Math.min(this.tasks.length, this.max - this.pool.length);
for(var i=0;i<min;i++){
var currTask = this.tasks.shift();
this.pool.push(currTask);
currTask().then(res=>{
console.log(new Date().getTime() - startTime);
}).catch(err=>{
}).finally(()=>{
this.pool.splice(this.pool.indexOf(currTask), 1);
this.run();
})
}
}
var pool = new taskPool();
for(let i=0;i<5;i++){
pool.addTask(function(){
return new Promise(resolve=>{
setTimeout(()=>{
resolve(i);
},500);
}).then(res=>{
console.log(‘resolved‘ ,res);
})
})
}
/**
输出:
resolved 0
500
resolved 1
500
resolved 2
1000
resolved 3
1000
resolved 4
1500
**/
var startTime =new Date().getTime()
function asyncPool(array, limit){
let index = 0;
let res = [];
let pool = [];
let run = function() {
if(index === array.length){
return Promise.resolve();
}
let item = array[index++];
let promise = Promise.resolve(item());
res.push(promise);
let e = promise.then(()=>{
pool.splice(pool.indexOf(e), 1);
})
pool.push(e);
console.log(`pool size : ${pool.length}`, pool);
let r = Promise.resolve();
if(pool.length >= limit){
r = Promise.race(pool);
}
return r.then(()=>run());
}
return run().then(()=>{
console.log(res);
return Promise.all(res);
});
}
var timeout = i => {
return function () {
return new Promise(resolve=>{
setTimeout(()=>{resolve(i)}, i);
})
}
}
asyncPool([timeout(600),timeout(300),timeout(700),timeout(400),timeout(500)], 2, timeout).then(res=>{
console.log(res);
console.log(new Date().getTime() - startTime);
})
/**
输出
[600, 300, 700, 400, 500]
1500
请求1 2 先发起; 1 2 起始时间 0
2请求完成 继续请求3; 3 起始时间 300
1请求完成 继续请求4; 4 起始时间 600
3请求完成 继续请求5; 5 起始时间 1000
5请求完成,所有请求完成,此时时间 1500
**/
原文:https://www.cnblogs.com/alohaplat/p/13644212.html