读源码async-pool有感:

    1. async function asyncPool(poolLimit, array, iteratorFn) {
    2. const ret = []; // 用于存放所有的promise实例
    3. const executing = []; // 用于存放目前正在执行的promise
    4. for (const item of array) {
    5. // 防止回调函数返回的不是promise
    6. const p = Promise.resolve().then(() => iteratorFn(item, array));
    7. ret.push(p);
    8. // then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除
    9. // 这里p.then()会返回一个promise实例对象
    10. const e = p.then(() => executing.splice(executing.indexOf(e), 1));
    11. executing.push(e);
    12. if (executing.length >= poolLimit) {
    13. // 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更,
    14. // 状态变更后,就会执行上面then的回调,将该promise从executing中删除,
    15. // 然后再进入到下一次for循环,生成新的promise进行补充
    16. await Promise.race(executing);
    17. }
    18. }
    19. return Promise.all(ret);
    20. }

    测试代码:

    1. const timeout = (i) => {
    2. console.log('开始', i);
    3. return new Promise((resolve) => setTimeout(() => {
    4. resolve(i);
    5. console.log('结束', i);
    6. }, i));
    7. };
    8. (async () => {
    9. const res = await asyncPool(2, [1000, 5000, 3000, 2000], timeout);
    10. console.log(res);
    11. })();

    参考:
    Promise并发控制
    async-pool官方实现