上次面试总有面试官问我知道promise吗,用过什么api吗,知道promise.all吗,我寻思着我知道啊,就是传一个数组,里面有你要执行的异步任务,作为一个异步任务队列,等全部完成以后,返回的res中会有几个异步任务的返回值,会以数组的形式返回。
面试官总是问有没有什么缺点,给我整蒙了,我一般知道的就是promise各种好,但是好多人问,我就下去查了下,终于知道了promise.all的缺点!
假设有三个异步任务,如果都执行成功,那么返回的值是三个异步任务的值。上代码。
Promise.all([Promise.resolve(1),Promise.resolve(2),Promise.resolve(3)])
.then(res=>{
console.log(res)},err=>console.log(err)) //[1,2,3]
如果有一个任务失败,那么返回这个失败的任务的值。
Promise.all([Promise.resolve(1), Promise.reject(2), Promise.resolve(3)])
.then(res => console.log(res),err=>console.log(err))
// 2
那么问题来了,只要有一个任务失败就不会走.then后面的方法,而且不会吐出你想要的全部返回值,只会吐出失败的返回值。
针对这个问题,有一个解决办法,我们知道.then吐出的是promise对象,说不清楚上代码。
var p = new Promise((resolve,reject)=>{
reject('失败了')
}).then(res=>{
console.log(res)
},err=>{
console.log(err)
}).then(res=>{
console.log('成功')
},err=>{
console.log('失败')
})
//失败了
//成功
第二个的then执行成功还是失败依第一个then而确定,第一个then中没有异步任务的时候,吐出的promise的状态是成功的,如果有return的话,可以传递return中的参数。
以此为例,我们的问题就有了解决办法。
Promise.all([Promise.reject(1).then(res=>console.log(res), err=>console.log(err)),
Promise.resolve(2).then(res=>console.log(res), err=>console.log(err)),
Promise.resolve(3).then(res=>console.log(res), err=>console.log(err))])
.then(res => console.log(res),err=>console.log(err))
//1
//2
//3
要求比较高的可以优化一下。
function handlePromise(promiseList) {
return promiseList.map(promise =>
promise.then(res=>(res),err=>(err))
)
}
Promise.promiseAll=function(promiseList){
return Promise.all(handlePromise(promiseList))
}
Promise.promiseAll([Promise.reject(1),Promise.resolve(2),Promise.resolve(3)]).then(res=>console.log(res),
err=>{console.log(err)})
//[1,2,3]