promise你知多少?

promise 三种状态:pedding(进行中)、fulfilled(已成功)、rejected(已失败)。

特点:状态不受外界的影响, 一旦状态改变就不会再变(pending–>fulfilled,pending–>rejected)。

Promise是一个构造函数,用来生成promise实例。

Promise构造函数接受一个函数作为参数,这个函数有两个参数。

<script>
    const p =new Promise(function(resolve,reject) {
        //resolve函数:将Promise对象从未完成变成成功,再异步操作成功的时候调用
        resolve()//返回异步操作的结果,结果作为参数传递
        //reject函数:将Promise对象从未完成变成失败,再异步操作失败的时候调用
        reject()//返回异步操作的结果,结果作为参数传递
    })
</script>

Promise实例方法

  • then():用于指定当 Promise 对象的状态从 “pending”(进行中)转变为 “fulfilled”(已成功)时应该执行的操作。
    在实际使用中,.then() 方法通常只提供一个 onFulfilled 回调,而错误处理则通过链式调用 .catch() 方法来完成。但 .then() 方法也完全有能力处理错误,只需要你提供两个回调函数即可。
    如果实例状态发生改变的回调函数,返回的是一个新的Promise实例,也就是Promise可以链式书写的原因。
<script>
    const p = new Promise(function(resolve,reject){
        setTimeout(()=>{
            const time = new Date().getTime()
            if(time%2==0){
                resolve('成功的数据,time='+time)
            }else {
                reject('失败的数据,time='+time)
            }
        })
    })
    p.then((value)=>{
    //fulfilled(已成功)的状态
        console.log(value)
    },(res)=>{
    //rejected(已失败)的状态
        console.log(res)
    })

</script>
//走resolve,打印
成功的数据,time=1722001440362

//走reject,则打印
失败的数据,time=1722001367327
  • catch()用于指定发生的错误回调,一般通过catch替代then中的第二个参数。
<script>
    const p = new Promise(function(resolve,reject){
        setTimeout(()=>{
            const time = new Date().getTime()
            if(time%2==0){
                resolve('成功的数据,time='+time)
            }else {
                reject('失败的数据,time='+time)
            }
        })
    })
    p.catch((value)=>{
        console.log(value)
    })
</script>
//如果走resolve就没有打印
//走是的reject
失败的数据,time=1722001511851
  • finally()用来指定不管Prormise对象状态最后如何,都会执行的操作。
<script>
    const p = new Promise(function(resolve,reject){
        setTimeout(()=>{
            const time = new Date().getTime()
            if(time%2==0){
                resolve('成功的数据,time='+time)
            }else {
                reject('失败的数据,time='+time)
            }
        })
    })
    p.then((value)=>{//resolved(已成功)的状态
        console.log(value)
    }).catch((value)=>{
        console.log(value)
    }).finally(()=>{
        console.log('end')
    })
</script>
//走resolve,打印
成功的数据,time=1722001602184 
end

//走reject,则打印
失败的数据,time=1722001795933 
end

回调地狱(多个串联的异步操作)

<script>
    setTimeout(()=>{
        console.log(1)
        setTimeout(() => {
            console.log(2)
            setTimeout(() => {
                console.log(3)
            }, 3000);
        }, 2000);
    },1000)
</script>
  • promise解决回调地狱
<script>
    function getData(){
        return new Promise((resolve,reject)=>{
            setTimeout(() => {
                console.log(1)
                resolve(2)
            }, 1000);
        })
    }
    getData().then((value)=>{
        return new Promise((resolve,reject)=>{
            setTimeout(() => {
            console.log(value)
            resolve(3)
            }, 2000);
        })
    }).then((value)=>{
        return new Promise((resolve,reject)=>{
            setTimeout(() => {
            console.log(value)
            }, 3000);
        })
    })
</script>
//打印
1
2
3

Promise 聚合

Promise 聚合的返回值都是返回一个新的Promise对象

  • Promise.all

    将多个Promise实例包装成一个新的Promise实例

<script>
    let p1 = new Promise((resolve,reject)=>{
        resolve('sucess01')
    })
    let p2 = new  Promise((resolve,reject)=>{
        // resolve('sucess02')
        reject('fail02')
    }).catch((res)=>{
        console.log('失败数据')
    })
    let p3 = new  Promise((resolve,reject)=>{
        resolve('sucess03')
        // reject('fail03')
    })
    //参数可以不是数组,但是必须是iterator
    let pAll=Promise.all([p1,p2,p3])
    console.log(pAll)
    //pAll的状态由p1,p2,p3来决定,只有三个都成功,pAll才会成功
    //只要有一个失败,就是失败,失败会返回第一个失败的数据
    //如果作为参数的实例,自己定义了catch方法,那么它一旦rejected,不会触发pAll的catch方法
    pAll.then((res)=>{
        console.log('pAll.then:'+res)
    }).catch((errors)=>{
        console.log('pAll.catch:'+errors)
    })
    //多个请求合并在一起,按顺序输出
    function getBannerList() {
        return new Promise((resolve,reject)=>{
            setTimeout(() => {
                resolve('轮播图的数据')
            }, 1000);
        })
    }
    function getMusicList() {
        return new Promise((resolve,reject)=>{
            setTimeout(() => {
                resolve('歌曲列表的数据')
            }, 2000);
        })
    }
    function getCatecList() {
        return new Promise((resolve,reject)=>{
            setTimeout(() => {
                resolve('歌单分类的数据')
            }, 3000);
        })
    }
    function initLoad(){
        let All = Promise.all([getBannerList(),getMusicList(),getCatecList()])
        console.log(All)
        All.then((value)=>{
            console.log(value)
        })
    }
    initLoad()
</script>
  • Promise.race
<script>
   let p1 =new Promise((resolve,reject)=>{
        setTimeout(() => {
             resolve('p1成功')
           }, 2000);
   })
   let p2 =new Promise((resolve,reject)=>{
        setTimeout(() => {
           resolve('p2成功')
           }, 1000);
   })
   //调用
   const prace = Promise.race([p1,p2])
   prace.then((value)=>{
       console.log(value)
   })
   //Promise.race:只要实例中有一个先改变的状态,
   //就会把这个实例的参数的返回值传给prace的回调函数
   //如果是then,先变化的都会获取到,如果catch第二个变化即使是rejected也不能捕捉到
   //使用场景:请求超时提示
   function request() {
       return new Promise((resolve,reject)=>{
           setTimeout(() => {
               resolve('请求成功')
           }, 4000);
       })
   }
   function timeout() {
       return new Promise((resolve, reject) => {
           setTimeout(() => {
               reject('网络不佳,请求超时')
           }, 3000);
       })
   }
   Promise.race([request(),timeout()]).then((value)=>{
       console.log(value)
   }).catch((res)=>{
       console.log(res)
   })
</script>
  • Promise.any
let promise1 = Promise.reject(0);  
let promise2 = new Promise((resolve) => setTimeout(resolve, 50, 'fast'));  
let promise3 = new Promise((resolve, reject) => setTimeout(reject, 100, 'slow'));  
  
Promise.any([promise1, promise2, promise3]).then((value) => {  
  console.log(value); // "fast",因为 promise2 最快成功  
}).catch((errors) => {  
  // 如果所有 promise 都失败了,或者没有 promise 被传入,则执行此代码块  
  console.log(errors); 
  // 如果所有 promise 都失败了,则 errors 是一个 AggregateError,会以 AggregateError 拒绝,包含所有失败的原因。  
});

Promise封装ajax

<script>
    function getJSON(url) {
        return new Promise((resolve, reject) => {
            //创建一个实例对象
            let xhr=new XMLHttpRequest()
            //新建一个http请求
            xhr.open('GET',url,true)
            //发送http请求
            xhr.send(null)
            //设置状态的监听函数
            xhr.onreadystatechange=function(){
                if(xhr.readyState!==4)return
                //当请求成功或者失败的,需要返回promise实例的状态
                if(xhr.status>=200||xhr.status<300){
                    resolve(xhr.response)//返回请求结果
                }else {
                    reject(new Error(xhr.statusText))
                }
            }
            //设置错误监听函数
            xhr.onerror=function(){
                reject(new Error(xhr.statusText))
            }
            //设置响应数据类型
            xhr.responseType = 'json'
        })
    }
    getJSON('https://home.firefoxchina.cn/').then((value)=>{
        console.log(value)
    }).catch(res=>{
        console.log(res)
    })
</script>
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值