Async Pool
通过这篇文章,能学习分别async-pool的ES6和ES7写法
ES6
const timeout = i => new Promise(resolve => setTimeout(() => {
console.log(i)
resolve(i)
}, i));
function asyncPoolES6(poolLimit, array, iteratorFn) {
let i=0
const ret = []
const executing = []
function enqueue() {
if(i === array.length)
return Promise.resolve()
const item = array[i++]
const p = Promise.resolve().then(() => iteratorFn(item, array))
ret.push(p)
let r = Promise.resolve()
if(poolLimit <= array.length) {
const e = p.then(() => executing.splice(executing.indexOf(e), 1))
executing.push(e)
if(executing.length >= poolLimit) {
r = Promise.race(executing)
}
}
return r.then(() => enqueue())
}
return enqueue().then(() => Promise.all(ret))
}
asyncPoolES6(2, [1000, 1000, 1000, 1000, 5000, 3000, 2000], timeout)另一篇的内容
es7版本
async function asyncPool(poolLimit, array, iteratorFn) {
const ret = []
const executing = [] // 用于存放并发限制的处于Pending状态的Promise对象
for(const item of array) {
// iteratorFn(item) 得到一个pending状态的Promise对象 p。(这里之所以不直接 p = iteratorFn(item),
// 是为了兼容iteratorFn是同步函数的场景,保证返回的p一定是Promose对象
const p = Promise.resolve().then(() => iteratorFn(item))
ret.push(p)
// 如果限制数量poolLimit 小于等于 数组的总长度再执行限制。当前poolLimit=3,arr.length=10,进入if逻辑
if(poolLimit <= array.length) {
// 根据刚刚的p创建一个Promise对象e,等p resolve的时候才执行then里的回调,把e从executing数组移除
const e = p.then(() => executing.splice(executing.indexOf(e), 1))
executing.push(e)
if(executing.length >= poolLimit) {
await Promise.race(executing)
}
}
}
return await Promise.all(ret)
}
const curl = (i) => {
console.log('开始', i)
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(i)
console.log('结束', i)
}, 1000 + Math.random()*1000)
})
}
let urls = Array(10).fill(0).map((v,i) => i);
(async () => {
const res = await asyncPool(3, urls, curl);
console.log(res);
})();Updated on 4/13/2023