promise学习之语法篇

    进阶使用

     手写promise

     常见面试题

前言

之前一直没有专门的去学过promise,只知道它可以用来解决'回调地狱',是异步的一种实践方式。最近在项目中遇到无痛感刷新token时,要用到promise的特性,故在此记录下学习历程。

promise解决的问题

关于异步使用的最多的就是发送ajax请求后台数据,当一个页面不止一个请求且请求有先后关系时,就会遇到"回调地狱"的问题,在不使用async+await的情况下,我们通常会写出类似下面的代码

        this.$axios.post(url,{}).then(res=>{

            if(res.data.code==200){

                this.$axios.post(url,{id:res.data.id}).then(resp=>{

                    if(resp.data.code==200){

                        console.log('接口请求完成')

                    }

                })

            }

        })

坦然,当请求的接口无限堆砌的时候,我们的代码会变得臃肿和难以阅读,当遇到bug我们很难直接进行定位,这不利于高效开发和代码维护,也不利于协同开发。

使用promise改写    

let p1 = new Promise((resolve,reject)=>{

     this.$axios.post(url,{}){

        if(res.data.code==200){

            resolve({id:res.data.id})

        }

    }

})

let p2 = new Promise((resolve,reject)=>{

        resolve(p1)

})

p2.then(res=>{

        this.$axios.post(url,{id:res.id}).then(resp=>{

                console.log('接口请求完成')

        })

})        

从视觉上看,我们将两次请求进行分开,结构更加清晰

promise语法

1-promise实例

    let p = new Promise((resolve,reject)=>{//使用new操作符实例化promise,会返回一个promise对象

            resolve() //发出成功通知

            reject()//发出失败通知

    }).then()  //then方法相当于一个拦截器,允许我们获取resolve或者reject抛出的值,如果为空,则会向下一个                           then传递

    .then(success=>{//接受resolve通知

    },error=>{//接受reject发出的通知

    })

2-特殊点--新promise实例必须抛出状态而then(finally、catch)方法返回的promise默认抛出resolve

    let p = new Promise((resolve,reject)=>{

        //如果不手动抛出状态那么打印p的结果为pending

        reject('出错了,请联系管理员')

    })

    let p2 = p.then(null,err=>{

        console.log(err) //通过.then拦截抛出状态,这里得到'出错了,请联系管理员'

    })

    let p3 = p2.then(ok=>{ //p2是p通过then返回的promise,会默认抛出resolve,因此将打印'ok'

        console.log('ok')

        return new Promise((resolve,reject)=>{ //如果想控制抛出状态,那么我们可以在then中return一个新的                                                                                     promise

                reject('阿哦,出错了~')

        })

    },error=>{

        console.log('error')

    })

    p3.then(null,reason=>{

        console.log(reason) //这里的p3是一个新的promise,因此将根据抛出状态进行捕获

    })

3-异常处理

    new Promise((resolve,reject)=>{

        //抛出错误

        reject('err msg')

        //或者

        throw new Error('err msg')

    }).then(null,err=>{//如果只有一个promise我们可以将then的第二个参数当作异常捕获的回调

    }).catch(err=>{//当存在链式promise时,我们可以使用catch来统一捕获异常并处理

    })

4-异步后处理

    new Promise((resolve,reject)=>{

        reject('err')

    }).catch(err=>{}).finally(()=>{

        //这里类似jquery中ajax请求的complete,我们可以在这里关闭一个loading动画

    })

5-resolve/reject的妙用

    let data = null,

        pre_id = '上一个接口数据';

    function getData(){

       //缓存

      if(data){

        //由于外部使用了promise语法获取函数返回值,因此不能直接return data

        return Promise.resolve(data)

      }

    if(!pre_id){

        return Promise.reject('接口缺少请求参数')

    }    

       return new Promise((resolve,reject)=>{

                this.$axios.get(url,{pre_id}).then(res=>{

                    data = res.data

                    resolve(data)

                })

        }) 

        .then(res=>{

            return res

        })

        .catch(err=>{})

        .finally(()=>{})

    }

    setInterval(()=>{

            getData().then(res=>console.log(res)).catch(err=>{})

    },1000)

6-批量执行promise

let p1 = new Promise((resolve,reject)=>{})

             .catch(err=>{})//如果p1单独进行了错误处理,那么all方法将无法监听到p1的resolve,all得到的是catch返回的                                                       promise,有默认的resolve

let p2 = new Promise((resolve,reject)=>{})

Promise.all([p1,p2]) //我们只需要给all方法传递一个由promise组成的数组,Promise就会批量进行调用

.then(res=>{ //这里的成功必须是p1和p2都抛出resolve状态,否则将走catch接口

}).catch(err=>{})

7-更松散的批量执行之allSettled

代码同6,在Promise.allSettled([p1,p2]).then(res=>{})//不强制p1p2均为resolve,永远不会走catch接口

8-龟兔赛跑之-race

let p1 = new Promise((resolve, reject) => {

            setTimeout(()=>{

                reject('网络错误')

            },180)

})

let p2 = new Promise((resolve, reject) => {

            setTimeout(()=>{

                resolve('ok')

            })

})

Promise.race([p1,p2]).then(res=>{

            console.log(res)

}).catch(err=>{

            console.log(err)

})

以上就是promise的语法内容

我们学习任何事物都是一次从无到有、从走到跑的过程,只有了解其存在的语法,才能在实战中运用起来,大家加油

你可能感兴趣的:(promise学习之语法篇)