const results = [];
const timeout = i =>
new Promise(resolve =>
setTimeout(() => {
results.push(i);
resolve();
}, i)
).then(() => {
return i
});
const urls = [100, 500, 300, 200]
class LimitPool {
constructor(max) {
this._max = max
this._idle = 0
this._queue = []
}
call(fn, ...args) {
return new Promise((resolve, reject) => {
const task = this._createTask(fn, args, resolve, reject)
if(this._idle >= this._max) {
// 大于目前通道数 放入队列中
this._queue.push(task)
} else {
task()
}
})
}
_createTask(fn, args, _resolve, _reject) {
// 惰性计算 如果返回,会直接计算fn,Promise的构造函数是直接运行的,不会异步执行
return () => {
fn(...args)
.then(_resolve)
.catch(_reject)
.finally(() => {
this._idle--
if (this._queue.length) {
const task = this._queue.shift()
task()
} else {
// console.log('队列清空完毕')
}
})
this._idle++
}
}
}
// 初始化请求池
const limitPool = new LimitPool(2)
// 多次请求同时发起,占满通道后会存储到this._queue队列中
// 等待前面的请求结束,通道释放后继续执行
for(let i of urls) {
limitPool.call(timeout, i).then(() => console.log(results))
}