promise基本使用

Promise是JS进行异步编程的新的解决方案(旧的是纯回调)

  语法上:Promise是一个构造函数

  功能上:Promise对象用来封装一个异步操作并可以获得其结果

 

Promise的状态改变

  成功:pending变为resolved,失败:pending变为rejected

  只有这两种,且一个promise对象只能改变一次

  无论成功还是失败,都会有一个结果数据

  成功的结构数据一般称为vlaue,失败的结果数据一般称为 reason

 

Promise的基本流程

new Promise( )  ->  执行异步操作

  ①成功:执行 resolve()  ->  Promise对象(resolved状态)->  回调 onResolved( )    then()         新的Promise对象

  ②失败:执行reject( )  ->  Promise对象(rejected状态)  -> 回调onRejected     then() / catch()       新的Promise对象

 

 //1,创建一个新的promise对象
    const p = new Promise((resolve,reject)=>{ //执行器函数是同步回调!
        console.log('执行excutor'); //立刻执行
        //2,执行异步操作
        setTimeout(()=>{
            const time = Date.now()
            if(time%2===0){
                resolve('成功的数据,time='+time); //3.1 如果成功了, 调用 resolve(value)
            }
            else{
                reject('失败的数据,time='+time); //3.2 如果失败了, 调用 reject(reason)
            }
        },1000)
        console.log('123'); //先输出执行 excutor
    })

    p.then(
        value=>{ //接收成功得到的value  onResolved(当成功的时候)
            console.log('成功的回调:',value)
        },
        reason=>{ //接收失败得到的reason   onRejected
            console.log('失败的回调:',reason)
        }
    )

    p.catch(
        reason=>{
            console.log('p.catch:',reason); // 接收得到失败的reason数据  onRejected 回调执行
        }
    )

    //执行excutor
    //123
    //成功的回调: 成功的数据,time=1590557706934 / 失败的回调: 失败的数据,time=1590557756329

 

为什么使用Promise?

对比不同回调方式:

1,指定回调函数的方式更加灵活(可以指定什么时候调用回调函数)

  ①纯回调,必须在启动异步任务前指定

    如:启动任务(audioSetting)前必须指定回调函数(callback)

      createAudioFileAsync( audioSetting , successCallback , failCallback )

  ②promise:启动异步任务=》返回promise对象=》给promise 对象绑定回调函数(甚至可以在异步任务结束后指定)

    如:可在启动任务(audioSetting)后指定回调函数(callback)

      const promise = createAudioFileAsync( audioSetting )

      setTimeout( () => {

        promise.then( successCallback , failCallback )

      } , 1000 )

2,支持链式调用,可以解决回调地狱问题

  回调地狱:回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调函数执行的条件( 不便于阅读 , 不便于异常处理 )

      

  解决方案:promise链式调用

      

  终极解决方案:async / await

      

 

 

    //1,查出当前用户信息
    //2,按照当前用户的id查出它的课程
    //3,按照当前课程id查出分数

    //回调地狱
    $.ajax({
        url:'./mock/user.json',
        success(data){
            console.log("用户信息:",data)
            $.ajax({
                url:`./mock/user_course_${data.id}.json`,
                success(data){
                    console.log("当前用户课程:",data);
                    $.ajax({
                        url:`./mock/course_score_${data.id}.json`,
                        success(data){
                            console.log("当前用户当前课程的分数:",data);
                        },
                        error(error){
                            console.log("查询当前用户当前课程分数异常:",error);
                        }
                    })
                },
                error(error){
                    console.log("查询当前用户课程异常:",error)
                }
            })
        },
        error(error){
            console.log("查询用户信息异常:",error)
        }
    })

    //promise调用方式
    function get(url,data){
        return new Promise((resolve,reject)=>{
            $.ajax({
                url:url,
                data:data,
                success:function(data){
                    resolve(data)
                },
                error:function(err){
                    reject(err)
                }
            })
        })
    }

    //调用封装后的方法
    get("./mock/user.json")
    .then((data)=>{
        console.log("查询用户信息成功:",data);
        return get(`./mock/user_course_${data.id}.json`)
    })
    .then((data)=>{
        console.log("查询当前用户当前课程成功:",data)
        return get(`./mock/course_score_${data.id}.json`)
    })
    .then((data)=>{
        console.log("查询当前用户当前课程分数成功:",data)
    })
    .catch((err)=>{
        console.log("出现异常:",err)
    })

  

  

posted @ 2020-05-27 14:12  shanlu  阅读(174)  评论(0编辑  收藏  举报