Promise.all Promise.race p.finally方法的使用和实现

Promise基本概念

a.一个promise实例有两个关键属性 如下图所示 PromiseState 称之为 promise实例的 状态
PromiseResult 称之为promise实例的 结果
b.下图可知一个promise实例有三种状态
成功(fulfilled) 失败(reject) 未改变(pedding)
c. 成功态 结果可在then回调中获取 失败态结果可有catch捕获或then的第二个回调中捕获
d. then catch 回调的执行是微任务 (queueMicrotask也是微任务)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

一.Promise.all

1.使用

let p1 = new Promise( (res,rej) =>{
    
    
    res(111)
})
let p2 = new Promise( (res,rej) =>{
    
    
 setTimeout(()=>{
    
    
    res(222)
 },2000)
})
let p3 = new Promise( (res,rej) =>{
    
    
    res(333)
})
Promise.all([p1,p2,p3]).then( data =>{
    
    
    console.log('data',data) // [111,222,333] 可以拿到数组所有成功的结果
}).catch(err =>{
    
    
    console.log("err",err)  // 只要有一个失败 就会拿到失败的结果 
})

2.特点

a.all方法返回一个promise实例对象(后面简称promise)
b. all方法返回的promise的状态 : 只要有一个是失败,状态就是失败,只有全部成功,才是成功
c. all方法返回的promise的结果 : 成功状态的结果 是一个数组 数组的每一项与传入的数组中的每一个promise的结果**一 一对应** , 失败状态时的结果是 数组中第一个状态为失败后的结果
d.数组中只要有一个是失败的promise 那么最终的结果就是失败 与数组中元素的顺序无关 与数组中状态改变的先后的顺序无关

3.实现

Promise.all = function (arr){
    
    
    // 暂不考虑数组中非promise实例的情况
    let successValue = []
    let times = 0
    return new Promise( (res,rej) =>{
    
    
        arr.forEach( (pro,index) =>{
    
    
            pro.then( data =>{
    
    
                times ++
                // 数组中promise的索引位置 要与all方法返回的promise的结果的数组中的索引位置一一对应
                successValue[index] = data 

                // 确保可以拿到数组中所有的promise的结果
                // 这里不能用successValue长度与arr的长度进行判断 因为[111,empty,333].length === 3 的情况 
                // 这意味着数组中还有一个promise的状态没有发生改变
                 if(times === arr.length){
    
    
                     // 说明所有的promise状态都成功改变
                     res(successValue)
                 }
            }).catch( err =>{
    
    
                rej(err)
            })
        })
    })
}

Promise.race

1.使用

let p1 = new Promise( (res,rej) =>{
    
    
    res(111)
})
let p2 = new Promise( (res,rej) =>{
    
    
    res(222)
})
let p3 = new Promise( (res,rej) =>{
    
    
    res(333)
})
Promise.race([p1,p2,p3]).then( (data) =>{
    
    
   console.log("data",data) // data 111
}).catch(err =>{
    
    
    console.log("err",err)
})

2.特点

a. Promise类上的静态方法
b. 获取数组中状态最先改变的结果

3.实现

Promise.race = function(proList){
    
    
    return new Promise( (res,rej)=>{
    
    
        proList.forEach( pro =>{
    
    
            pro.then( data =>{
    
    
                res(data)
            },(err)=>{
    
        // 这里使用.catch 会有问题
                rej(err)
            })
        })
    })
}

Promise.finnaly

1.使用

let p1 = new Promise( (res,rej) =>{
    
    
    rej(111)
})
p1
.finally((finallyData) =>{
    
    
    console.log("成功失败都会执行",finallyData) // 成功失败都会执行 undefined
})
.then((data) =>{
    
    
    console.log("成功的回调",data)             // 成功的回调 111
})
.catch(err =>{
    
    
    console.log("失败的回调",err)
})

2.特点

a. finally回调是微任务,是Promise原型上的方法
b. 不管成功还是失败都会执行回调

3.实现

Promise.prototype.finally = function(cb){
    
    
  return  this.then((data)=>{
    
    
        cb()
        return data
    },(err)=>{
    
    
        cb()
       throw err
    })
}

猜你喜欢

转载自blog.csdn.net/qq_33418013/article/details/123143024