Promise.all()接收一个数组为参数,当数组的所有Promise都为resolve的状态时,Promise.all()才会成功;若有一个失败,都会被认为是失败的。简单看一个下面的例子
var p1 = Promise.resolve('a');
var p2 = Promise.resolve('b');
var p3 = Promise.resolve('c');
Promise.all([p1,p2,p3]).then(value => {
console.log(value);
})
不用怀疑,上面这段代码的运行结果就是a,b,c。因为p1,p2,p3都是成功的状态。那么再继续看下一个例子:
var p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result)
.catch(e => e);
var p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
})
.then(result => result)
.catch(e => e);
Promise.all([p1,p2])
.then(value => {
console.log(value);
})
.catch(err => {
console.log(err);
})
此时大家的第一个想法是不是这个all会失败呢?嗯,其实我开始也是这样认为的,但是认真分析一下这段代码就会发现其实并不是我们想的那么简单的。下面我们来分析一下:
- p1肯定毫无疑问是成功的;
- p2在函数里直接抛出一个错误。但是注意了,p2有自己的catch的函数,catch函数是可以捕获到前面抛出的错误的;
- 因为p2自己可以捕获到错误,所以在Promise.all()方法里p1,p2两个Promise都是resolve的状态,因此会调用then方法指定的回调函数。
最后我们再看一下实现Promise.all()方法的过程。这里我们一定要明确这个方法接收的参数是数组并且返回的是promise对象。
//判断是不是一个promise
function isPromise(value){
if(typeof value === 'function' || (typeof value === 'undefined' && value != null)){
if(typeof value.then === 'function'){
return true;
}
}
return false;
}
Promise.all = function(values){
return new Promise((resolve,reject)=>{
let arr = [];
let i = 0;
let processData = function(key,value){
arr[key] = value;
if(++i === values.length){
resolve(arr)
}
}
for(let i = 0; i < values.length; i++){
let current = values[i];
if(isPromise(current)){ //判断传进来的是promise还是普通数据
current.then(y=>{
processData(i,y)
},reject)
}else{
processData(i,current)
}
}
})
}