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]
複製代碼
相關文章
相關標籤/搜索