这个是从git上找到的一个实现异步池的方法
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));
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));
}
poolLimit:并行最大任务数 array:迭代数组 iteratorFn:迭代执行函数 缺点是只能传一个固定的异步方法,然后将参数都放在一个数组内,用起来不方便。
参考前人的经验,我实现了一个可随时添加新任务到等待队列的任务池,按照入队顺序将任务放入任务池执行
class AsyncPool {
executing = [];
constructor(poolLimit) {
this.poolLimit = poolLimit || 5;
}
//promiseCreator:返回值为promise的任务函数
add(promiseCreator) {
if (this.executing.length < this.poolLimit) {
const p = Promise.resolve().then(() => promiseCreator());
const e = p.then((res) => {
this.executing.splice(this.executing.indexOf(e), 1);
return res;
});
this.executing.push(e);
return e;
} else {
const race = Promise.race(this.executing);
return race.then(() => this.add(promiseCreator));
}
}
}
测试:
const pool = new AsyncPool(2);
const startTime = new Date().getTime();
const createTask = (task, time) => () =>
new Promise((resolve) => {
const endTime = new Date().getTime() - startTime;
console.log(`${endTime}ms--------${task}开始执行`);
setTimeout(() => {
resolve();
const endTime = new Date().getTime() - startTime;
console.log(`${endTime}ms--------${task}执行完毕,花费${time}ms`);
}, time);
}).catch((err) => {});
const task1 = createTask("task1", 100);
const task2 = createTask("task2", 500);
const task3 = createTask("task3", 300);
const task4 = createTask("task4", 100);
pool.add(task1);
pool.add(task2);
pool.add(task3);
pool.add(task4);