可以實現 經過輸入限制併發的數量,對Promise 請求隊列 進行控制web
思路:數組
經過閉包維護 結果數組
,正在處理的數量
,已經處理完的數量
固然也能夠用class 實現promise
封裝run 方法,run方法爲核心代碼閉包
併發 經過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]
複製代碼