可并发控制的 Promise.all
纯自己整的,不确定这样的实现是否正确,也不确定测试是否有说服力。
还是期待讨论和指教。
实现代码
Promise.myAllConcurrent = function (promiseArr, limit = 1) {return new Promise((resolve, reject) => {if (!promiseArr[Symbol.iterator]) {throw new TypeError(`${promiseArr} is not iterable`);}if (!Array.isArray(promiseArr)) {promiseArr = Array.from(promiseArr);}const resArr = [];const len = promiseArr.length;let count = 0;let lastIndex = limit - 1;// 不能用 count 来替代 lastIndex// eg. 允许并发数为 3, 但总共有 10 个// 任务 ① 处理完后, 开始处理任务 ④// 假设任务 ④ 耗时较长,// 任务 ④ 结束之前, 任务 ② 也处理好了// 如果按照 count 去处理, 则此时任务 ③ 的回调会去处理任务 ②, 而非 任务 ⑤// 如果按照 lastIndex 去处理, 则此时任务 ③ 的回调会去处理任务 ⑤function takeOnePromise(resArr, index) {Promise.resolve(promiseArr[index]).then(value => {resArr[index] = value;count++;lastIndex++;if (count !== len) takeOnePromise(resArr, lastIndex);else resolve(resArr);},reason => {reject(reason);});}const top = Math.min(limit, length);for (let i = 0; i < top; i++) {takeOnePromise(resArr, i);}});}
测试代码
Promise.myAllConcurrent = function (promiseArr, limit = 1) {return new Promise((resolve, reject) => {if (!promiseArr[Symbol.iterator]) {throw new TypeError(`${promiseArr} is not iterable`);}if (!Array.isArray(promiseArr)) {promiseArr = Array.from(promiseArr);}const resArr = [];const len = promiseArr.length;let count = 0;let lastIndex = limit - 1;function takeOnePromise_timer(resArr, index) { // 为了测试, 包了一层计时器setTimeout(() => {Promise.resolve(promiseArr[index]).then(value => {resArr[index] = value;count++;lastIndex++;if (count !== len) takeOnePromise_timer(resArr, lastIndex);else resolve(resArr);},reason => {reject(reason);});}, 2000);}for (let i = 0; i < limit; i++) {// takeOnePromise(resArr, i);takeOnePromise_timer(resArr, i);}// 计时器 定时查询 res的数量, 以此代替观测并发数setInterval(() => {console.log(resArr.length);}, 1000);});}const instance1 = new Promise(resolve => {resolve('Promise —— 1');});const instance2 = new Promise(resolve => {resolve('Promise —— 2');});const instance3 = new Promise(resolve => {resolve('Promise —— 3');});const instance4 = new Promise(resolve => {resolve('Promise —— 4');});const instance5 = new Promise(resolve => {resolve('Promise —— 5');});const promiseArr = [instance1, instance2, instance3, instance4, instance5];Promise.myAllConcurrent(promiseArr, 2).then((value) => {console.log('finish —— promise');console.log('value: ', value);});
