模拟实现Promise.all
一、前言
Promise.all 是es2015的Promise内置的一个静态方法,接受一个promises
数组,返回一个新的promise:
- 如果
promises
数组的每一项的状态都变为fulfilled ,将返回的每一个promise 的结果按照原来数组的顺序,封装为一个新的数组作为成功的结果。- 如果其中一个promise 的状态变为rejected, 就返回该promise
二、准备测试数据
const promisesSuccess = []; // 五个成功的promise 数组
const promises = []; // 随机的promise
for (let i = 0; i < 5; i++) {
// 成功的promise
promisesSuccess.push(
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${i * 1000}--resolve`);
}, i * 1000);
})
);
// 随机promise
Math.random() > 0.1
? promises.push(
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${i * 1000}--resolve`);
}, i * 1000);
})
)
: promises.push(
new Promise((resolve, reject) => {
setTimeout(() => {
reject(`${i * 1000}--reject`);
}, i * 1000);
})
);
}
三、实现Promise.all
1. 乞丐版:
Promise.myAll = (promises) => {
const arr = [];
return new Promise((resolve, reject) => {
promises.forEach((item, index) => {
Promise.resolve(item).then((res) => {
arr.push(res);
if (arr.length === promises.length) resolve(arr);
}, (reason)=>{
reject(reason)
});
});
});
};
乞丐版存在的问题:
- 返回的数组没有按照原本的顺序,而是按照peomise 完成的顺序加入数组
- 错误可以简写。
注意: 如果不额外定义一个length ,代码如下:
Promise.myAll = (promiseArr) => {
const arr = [];
return new Promise((resolve, reject) => {
promises.forEach((item, index) => {
Promise.resolve(item).then((res) => {
arr[index] = res;
if (arr.length === promises.length) resolve(arr);
}, reject);
});
});
};
分析: 如果promiseArr
数组的 的最后一项先完成,此时的arr为[empty,empty,...,empty, res]
,显然此时的arr.length === promiseArr.length 成立,导致出错。
2. 完整版
Promise.myAll = (promiseArr) => {
const arr = [];
let count = 0;
return new Promise((resolve, reject) => {
promises.forEach((item, index) => {
Promise.resolve(item).then((res) => {
arr[index] = res;
count += 1;
if (count === promises.length) resolve(arr);
}, reject);
});
});
};
四、 测试
Promise.myAll(promisesSuccess).then(
(res) => {
console.log(res);
},
(reason) => {
console.log(reason);
}
);
Promise.myAll(promises).then(
(res) => {
console.log(res);
},
(reason) => {
console.log(reason);
}
);
执行结果:
原文链接:https://juejin.cn/post/7355088718371930122 作者:Rock1688