Promise 并发控制 简单实现

目标

可以实现 经过输入限制并发的数量,对Promise 请求队列 进行控制web

实现

思路:数组

  1. 经过闭包维护 结果数组正在处理的数量已经处理完的数量 固然也能够用class 实现promise

  2. 封装run 方法,run方法为核心代码闭包

    1. 可以判断正在执行的promise 数量
    2. 当promise 所有处理结束,触发resolve方法,输出resArr
  3. 并发 经过for循环实现,执行run 方法并发

//简化的type : (limitNum,promiseList)=>Promise
function createLimitPromise(limitNum, promiseList) {
  let resArr = [];
  let handling = 0;
  let resolvedNum = 0

  return new Promise(resolve => {
    //因为promiseList长度在改变,因此经过runtime 保存
    const runTime = promiseList.length;
    //并发执行promise
    for (let i = 0; i < runTime; i++) {
      //此处传递promiseList 是为了避免破坏原Promise List
      run([...promiseList]);
    }
    //核心代码 执行
    function run(promiseList) {
      if (handling < limitNum && promiseList.length) {
        handling += 1;
        handle(promiseList.shift())
          .then(res => {
            resArr.push(res);
          }).catch(e=>{
              //ignore 
              console.log('catch error')
          })
          .finally(() => {
            handling -= 1;
            resolvedNum += 1
            console.log(`resolvedNum : ${resolvedNum}`)
            if (resolvedNum === runTime) resolve(resArr);
            run(promiseList);
          });
      }
      
    }
    //辅助代码 Promise => Promsie
    function handle(promise) {
      return new Promise((resolve, reject) => {
        promise.then(res => resolve(res)).catch(e => reject(e));
      });
    }
  });
}
复制代码

测试

6 个promise 请求, 模拟正常请求和错误请求两种状况测试

let promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 2000);
});
let promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(2);
  }, 2000);
});
let promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(3);
  }, 2000);
});
let promise4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(4);
  }, 3500);
});
let promise5 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(5);
  }, 5000);
});
let promise6 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(6);
  }, 600);
});
let promiseList = [promise1, promise2, promise3, promise4, promise5, promise6];

const websiteLimit = createLimitPromise(3, promiseList);
websiteLimit.then(res => {
  console.log(res);
});

复制代码

输出ui

resolvedNum : 1
resolvedNum : 2
catch error
resolvedNum : 3
resolvedNum : 4
resolvedNum : 5
resolvedNum : 6
Array(5) [1, 2, 6, 4, 5]
复制代码
相关文章
相关标签/搜索