思路
Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。 —— MDN里Promise.all()的描述
- Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入。 —— 说明所传参数都具有Iterable,也就是可遍历。
- 并且只返回一个Promise实例。—— 说明最终返回是一个Promise对象。
- 那个输入的所有promise的resolve回调的结果是一个数组。—— 说明最终返回的结果是个数组,且数组内数据要与传参数据对应。
- 这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。—— 说明最终返回时,要包含所有的结果的返回。
- 它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。—— 说明只要一个报错,立马调用reject返回错误信息。
代码实现
const PromiseAll = (iterator) => {
const promises = Array.from(iterator); // 对传入的数据进行浅拷贝,确保有遍历器
const len = promises.length; // 长度
let index = 0; // 每次执行成功+1,当等于长度时,说明所有数据都返回,则可以resolve
let data = []; // 用来存放返回的数据数组
return new Promise((resolve, reject) => {
for (let i in promises) {
promises[i]
.then((res) => {
data[i] = res;
if (++index === len) {
resolve(data);
}
})
.catch((err) => {
reject(err);
});
}
});
};
const promise1 = Promise.resolve('promise1');
const promise2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 2000, 'promise2');
});
const promise3 = new Promise(function (resolve, reject) {
setTimeout(resolve, 1000, 'promise3');
});
PromiseAll([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});