Promise学习笔记

什么是Promise?

    1、抽象表达:是JavaScript中进行异步编程的新的解决方案(旧的指的是纯回调式的用法)。

    2、具体表达:

        (1)从语法上来说:promise是一个构造函数

        (2)从功能上来说:promise对象用来封装一个异步操作并且可以获取其结果

Promise的状态改变

promise一共有三个状态:pending、resolved、rejected。

    1、pending变为resolved

    2、pending变为rejected

        说明:pending变化的状态只有这俩种,且一个promise对象只能改变一次,无论变为成功还是失败,都只会有一个结果数据,成功的结果数据一般称为value,失败的数据结果一般称为reason。

promise操作流程图


Promise学习笔记_第1张图片
promise操作流程图

写一个基本的promise操作:

 /*            

简单的promise操作流程:

                1、创建一个新的promise对象

                2、执行一个异步任务

                3、判断异步操作成功与否:

                    3.1、成功:调用resolve(value) 

                   3.2、失败:调用reject(reason) 

       */
    const p = new Promise((resolve,reject) =>{ // 创建一个新的promise对象 ,相当于一个执行器函数

            // 执行一个异步操作任务

            setTimeout(() => { 

                const time = Date.now() // 生成一个现在的时间

                if (time %2 == 0) {

                    // 表示成功,调用resolve(value)

                    resolve("成功的数据是 "+time)

                } else {

                    // 表示失败,调用reject(reason)

                    reject('失败的数据是 '+time)

                }

            },1000)

        })

        p.then(

            value => {  //接收得到成功的数据

                console.log('成功的回调 ' + value)

            },

            reason => {    //接收得到失败的数据

                console.log('失败的回调' + reason)

            }

        )

为什么要用Promise

    指定回调函数的方式更灵活

        1、旧的:必须在启动异步任务之前指定。

        2、promise:启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定/多个)


例1——纯回调函数实现

    // 使用纯回调函数实现一个回调

        function successCallback(result){   //手动创建一个成功的回调函数

            console.log('声音文件创建成功:' + result)

        }

        function failureCallback(error){

            console.log('声音文件创建失败:' + error)

        }

        createAudioFileAsync(audioSetting,successCallback,failureCallback)  //创建一个创建音频的异步任务

        /*

            1、使用纯回调函数首先要定义好俩个回调函数再去启动异步任务

       如果使用promise的话,指定回调函数的方式更加灵活,不一定要在执行器函数之前就设置回调函数,可以在启动异步任务之后,甚至可以在有了结果之后再设定回调函数

        */

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

        1、什么是回调地狱? 

            多个串联的异步操作,就会出现回调地狱,通常还以上个回调函数的结果进行处理

            回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调执行的条件

        2、回调地狱的缺点

            不方便阅读,不方便异常处理

例:简单的地狱回调的形式

         doSomething(function(result){   //这个函数调用后结果为result,传给下一层函数
            doSomethingElse(result,function(newResult){     //把上层的result作为条件,再指定成功的回调和失败的回调成功的回调会生成全新的结果newResult

                doThirdThing(newResult,function(finalResult){   //把上层成功回调的结果再拿来当做条件,给他设置成功回调和失败回调

                    console.log('回调地狱的简单模板,多个异步操作串联')

                },failureCallback)

            },failureCallback)

        },failureCallback)

采用promise的链式调用解决回调地狱问题

    优点:1、代码可阅读性高

                2、统一异常处理,异常处理方便

        // 采用promise的链式调用解决回调地狱

        doSomething()   //  得到promise对象,启动异步任务(一个promise对应一个异步任务)

        .then(function(result){     //成功的回调result,调用第二个异步任务,返回一个新的promise 

            return doSomethingElse(result)  //把这个result结果作为成功传递给下一层的异步任务

        })

        .then(function(newResult){  //获取到doSomethingElse的成功回调newResult,并且继续向下传递

            return doThirdThing(newResult)

        })

        .then(function(finalResult){ //获取到doThirdThing的成功回调finalResult

            console.log('使用promise的链式形式解决回调地狱') // final成功回到的结果

        })

        .catch(failureCallback) // 统一处理异常,称为异常传透

 3、解决方案

            async/await

使用async/await解决终极解决回调地狱的问题

        async function request(){

            try{

                const result = await doSomething()

                const newResult = await doSomethingElse(result)

                const finalResult = await doThirdThing(newResult)

                console.log('用async/await终极解决回调地狱问题'+ result + newResult + finalResult)

            } catch(error){

                console.log(error)

            }

        }

Promise的API(语法)

        1、Promise构造函数:promise(excutor){}

            excutor函数:同步执行(resolve,reject) => {}     执行器函数

            resolve函数:内部定义成功时我们调用的函数 value => {}

            reject函数:内部定义失败时我们调用的函数 reason => {}

        说明:excutor(执行器函数)会再Promise内部立即同步回调,异步操作在执行器中执行

        2、Promise.prototype.then方法:(onResolved,onRejected) => {}

            onResolved函数:成功的回调函数  (value) => {}

            onRejected函数:失败的回调函数  (reason) => {}

        说明:指定用于得到成功value的成功回调和用于得到失败reason的失败回调。

              返回一个新的promise对象   


        3、Promise.prototype.catch方法:(onRejected) => {}

            onRejected函数:失败的回调函数(reason) => {}

        说明:then()的语法糖,相当于:then(undefined,onRejected)

        4、Promise.resolve方法: (value) => {}

            value:成功的数据或promise对象

        说明:返回一个成功/失败的promise对象

        5、Promise.reject方法:(reason) => {}

            reason:失败的原因

        说明:返回一个失败的promise对象

        6、Promise.all方法:(promise) => {}

            promise:包含n个promise的数组

        说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败就直接失败

        7、Promise.race方法:(promise) => {}

            promises:包含n个promise的数组

        说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态

Promise的异常抛出

    promise也可以使用异常抛出,抛出后promise的状态为rejected

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

            // resolve(1)    promise变为resolved成功的返回状态

            // reject(2)    promise变为rejected失败的返回状态

            // throw new error('出错了')    抛出异常,promise变成rejected失败状态,reason为 抛出的异常

            throw 3

        })

        p.then(

            value => {

            },

            reason => {

                console.log('reason ' + reason)

            }

        )

promise状态和指定回调函数先后问题

 (1)都有可能,正常情况下时先指定回调再改变状态,但也可以先改变状态再去指定回调

            (2)如何先改变状态再指定回调?

                1、在执行器中直接调用resolve()/reject()

                2、延迟更长时间才调用then()

            (3)什么时候才能得到数据

                1、如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据

                2、如果先改变状态,那当指定回调时,回调函数就会调用,得到数据

例:先指定回调函数,后改变状态值

        new Promise((resolve,reject) => {

            setTimeout(() => {

                reject(1)  // 后改变状态(同时指定数据),异步执行回调函数

            },1000)

        }).then(    // 先指定回调函数,保存当前指定的回调函数

            value => {},

            reason => {console.log('reason', reason)}

        )

例:先改变状态值,后指定回调函数

        new Promise((resolve, reject) => {

            resolve(1)  // 先改变的状态(同时指定数据)

        }).then(    // 后指定回调函数,异步执行回调函数

            value => {

                console.log('value2',value)

            }

        )

Promise.then()返回的新的promise的结果状态由什么决定?

    (1)简单表述:由then()指定的回调函数执行的结果决定

    (2)详细表达:

        1、如果抛出异常,新promise变为rejected,reason为抛出的异常

        2、如果返回的是非promise的任意值,新promise变为resolved,value为返回的值

        3、如果返回的是另一个新promise,次promise的结果就会成为新promise的结果

Promise异常传透

    (1)当使用promise的then链式调用时,可以在最后指定失败的回调

    (2)当前面任何操作出了异常,都会传到最后的回调中处理

    中断promise链

        (1)当使用promise的then链式调用时,在中间中断,不在调用后面的回调函数

        (2)办法:在回调函数中返回一个pendding状态的promise对象


自定义(手写)promise

才艺展示级别,学不会了,等啥时候我觉的我行了我再来学学看!

你可能感兴趣的:(Promise学习笔记)