美文网首页
promise学习之语法篇

promise学习之语法篇

作者: 习惯水文的前端苏 | 来源:发表于2020-03-22 20:21 被阅读0次

    前言

    之前一直没有专门的去学过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实战部分可以参考这个哦:https://www.jianshu.com/p/e107b454bf20)

    相关文章

      网友评论

          本文标题:promise学习之语法篇

          本文链接:https://www.haomeiwen.com/subject/iikvyhtx.html