// 每个时刻并发执行的promise数量是固定的,最终的执行结果还是保持与原理的promise.all一致
// 通过控制promise的实例化来控制并发
/**
* @param poolLimit 并发数量
* @param array 并发请求
* @param iteratorFn
*/
function asyncPool(poolLimit, array, iteratorFn){
let i = 0;
const ret = []
const executing = []
const enqueue = function(){
// 边界处理
if(i === array.length){
return Promise.resolve()
}
const item = array[i++]
const p = Promise.resolve().then(() => iteratorFn(item, array))
}
}
const timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i))
class LimitPromise {
constructor(max){
this._max = max
this._count = 0
this._taskQueue = []
}
call(caller, ...args){
return new Promise((resolve,reject) => {
const task = this._createTask(caller, args, resolve, reject)
if(this._count >= this._max){
this._taskQueue.push(task)
}else{
task()
}
})
}
_createTask(caller, args, resolve, reject){
return () => {
caller(...args).then(resolve).catch(reject)
.finally(() => {
this.count--
if(this._taskQueue.length){
let task = this._taskQueue.shift()
task()
}else{
console.log('清空队列')
}
})
this._count++
}
}
}
const request = function(){
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve()
},3000)
})
}
const limitRequest = new LimitPromise(2)
limitRequest.call(request)
limitRequest.call(request)
limitRequest.call(request)
limitRequest.call(request)
limitRequest.call(request)
limitRequest.call(request)
limitRequest.call(request)
limitRequest.call(request)
limitRequest.call(request)
var urls = [
'https://www.kkkk1000.com/images/getImgData/getImgDatadata.jpg',
'https://www.kkkk1000.com/images/getImgData/gray.gif',
'https://www.kkkk1000.com/images/getImgData/Particle.gif',
'https://www.kkkk1000.com/images/getImgData/arithmetic.png',
'https://www.kkkk1000.com/images/getImgData/arithmetic2.gif',
'https://www.kkkk1000.com/images/getImgData/getImgDataError.jpg',
'https://www.kkkk1000.com/images/getImgData/arithmetic.gif',
'https://www.kkkk1000.com/images/wxQrCode2.png'
];
function loadImg(url) {
return new Promise((resolve, reject) => {
const img = new Image()
setTimeout(() => {
console.log('一张图片加载完成');
resolve()
},2000)
// img.onload = function () {
// resolve();
// }
// img.onerror = reject
// img.src = url
})
};
function loadAllImg(){
let count = 0;
let max = 3;
let waiting = []
for(let key of urls){
if(count >= 3){
waiting.push(
function(){
loadImg(key).then(() => {
count --
let fn = waiting.shift()
fn && fn()
})
}
)
}else{
console.log('触发')
loadImg(key).then(() => {
count --
let fn = waiting.shift()
fn && fn()
})
count ++
}
}
}
loadAllImg()
console