自主实现 Promise.all
源码
const p = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
.reverse()
.map(
(it) =>
new Promise((resolve, reject) => setTimeout(() => resolve(it), it * 1000))
);
function promiseAll(array) {
return new Promise((resolve, reject) => {
const results = [];
let resolveCount = 0;
const length = array.length;
array.forEach((it, i) => {
it.then(
(value) => {
results[i] = value;
resolveCount++;
if (resolveCount === length) {
resolve(results);
}
},
(error) => {
reject(error);
}
);
});
});
}
promiseAll(p).then((values) => {
console.log(values);
});
分析
- 为什么要进行倒序?这样可以彻底的暴露出采用索引的方式判断是否可以裁决的这一方案的巨大弊端!
- 实现函数的参数是一个 Promise 数组,为了保证返回数据的顺序与输入一致,所以我引入了索引。
- 需要特别注意判断结束的位置,是在 then 回调取得值时,这个特别重要。
如果看不懂,建议温习一下 JavaScript 的词法作用域,闭包的概念。
附弊端结果:
测试环境:nodejs(v12.16.1)