Promise 笔记

110 阅读4分钟

回调函数

回调函数是什么

自己定义的,没有调用,最终执行了。

同步的回调函数

理解:立即在主线程上执行,不会放入回调队列中

举例: 数组遍历相关的回调函数Promise 的 executor 函数

异步的回调函数

理解:不会立即执行,会放入回调队列以后执行。

举例:定时器的回调,Promise的成功/失败的结果/ajax的回调

代码浏览器报错

Error所有错误的父类型
ReferenceError引用的变量不存在
TypeError数据类型不正确
SyntaxError语法错误

Promise 理解笔记

Promise是js中解决异步编程的新方案(旧的方案为,纯粹的回调函数) (Promise本身是同步的)

Promise是一个状态机,它可以被分为三种状态:pending(进行中)、fulfilled(已完成)、rejected(已失败)

    // 具体的表达
    //从语法上说:  Promise是一个内置的构造函数
    //从功能上说:  Promise的实例对象可以用来封装一个一部操作,并可以获取成功/失败的值。

理解

    // 1.Promise 不是回调,是一个内置的构造函数,在new 的时候调用
    // 2.Promise的构造函数接受一个函数作为参数,(要传入一个回调函数),并且是一个同步函数;MDN将此函数称之为executor函数。它是同步的回调,会立即在主线程上执行
    // 3.每一个Promise实例在刚被new出来的那一刻,状态都是初始化状态,即pending。
    // 4.executor函数有俩个参数,resolve,reject,都是函数,用来处理Promise的状态变化。
    // (1)调用resolve,会让Promise的状态变为fulfilled,同时可以指定成功的value值。
    // (2)调用reject,会让Promise的状态变为rejected,同时可以指定失败的reason(原因)值。
    
      let p = new Promise((resolve, reject) => {
        // console.log(resolve, reject);
        // console.log(reject('hello,该参数是失败的值'));
       resolve('hello,该参数是成功的值','45');
      }).then((resolve)=>{
        console.log(resolve);
      }).catch((reject)=>{
        console.log(reject);

      })

      
      

状态值的改变

        // Promise的实例状态有三种:pending、fulfilled、rejected
        // (1)执行resolve(value)方法,改变状态为fulfilled,并且设置结果值
        // (2)执行reject(reason)方法,改变状态为rejected,并且设置结果值
        // (3)执行器函数,抛出异常:如果当前是pending状态,则改变状态为rejected,并且设置结果值
        //  需要注意的是: Promise 的状态只能改变一次

Promise.all与Promise.race

        // Promise.all() 方法有一个参数,这个参数是一个数组,数组里面的每一项都是一个 Promise 对象。
        // 一个失败,就返回失败的结果
        // 当数组里面的每一项都执行完成后,Promise.all() 方法会返回一个新的 Promise 对象,这个新的 Promise 对象会在数组里面的每一项都执行完成后才执行。
        
        let p1 = Promise.resolve(1);
        let p2 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(2);
            }, 1000);
        });
        let p3 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(3);
            }, 2000);
        });


        let p4 = Promise.all([p1, p2, p3])
        p4.then(data => {
            console.log(data)
        }).catch(
            err => {
                console.log(err);
            }
        )
        
        // Promise.race() 类似一个赛道的形式;那个promise先执行完成就输出那个结果;不论成功还是失败

链式调用(用来解决回调地狱的问题)

        // Promise  实例 .then()  返回的是一个新的Promise实例,这个新的Promise实例会根据状态来执行下一步的操作。
        // 1:如果then所指定的回调返回的是非Promise值
        //   那么--新的Promise实例的状态为:成功(fulfilled),成功的value为a
        // 2:如果then所指定的回调返回的是一个Promise实例
        //   那么--新的Promise实例的状态,值,都与p一致
        // 3:如果then所指定的回调抛出异常:
        //   那么--新的Promise实例的状态为:失败(rejected),失败的reason为抛出的那个异常
       let p1 = new Promise((resolve, reject) => {
            setTimeout(() => {
                reject('success');
            }, 1000);
        })

        p1.then(
            value => {
                console.log('成功1', value); return Promise.reject('a')
            }, reason => {
                console.log('失败1', reason);
            }
        ).then(
            value => {
                console.log('成功2', value); return true
            }, reason => {
                console.log('失败2', reason); return 100
            }
        ).then(
            value => {
                console.log('成功3', value); return false
            }, reason => {
                console.log('失败3', reason); return false
            }
        ).then(
            value => {
                console.log('成功4', value); return -100
            }, reason => {
                console.log('失败4', reason); return false
            }
        );

        // 输出 
        // 失败1 success
        // 60 成功2 undefined
        // 66 成功3 true
        // 72 成功4 false

async与await(解决回调地狱的终极方案)

asyncawait 是es7提出的解决异步的方案

await必须在async修饰的函数中使用(可以获取到成功的结果)

如果想要获取失败的原因,需要通过try {
} catch (error) {
}   来捕获处理。

并且await 必须搭配async 使用不能单独使用

一个async可以搭配多个await使用反之不可

宏任务与微任务

        // 宏任务与微任务
        // 事件,ajax,定时器是一个宏任务/宏队列
        // 每一个宏任务在执行的同时,必须要保证微任务当中没有任务了
        
        // Promise是一个微任务/维队列
        // 目前经常用到的只有一个promise实例,属于微任务
        // 微任务优先级高于宏任务

        setTimeout(() => {
            console.log('setTimeout1');
        });
        setTimeout(() => {
            console.log('setTimeout2');
        });
        Promise.resolve().then(() => {
            console.log('Promise.resolve1');
        });
        Promise.resolve().then(() => {
            console.log('Promise.resolve2');
        });
        
        //输出:setTimeout1,setTimeout2,Promise.resolve1,Promise.resolve2
      setTimeout(()=>{
            console.log('0');                   //宏任务       
        },0);
        new Promise((resolve,reject)=>{        //微任务
            console.log('1');
            resolve();
        }).then(()=>{
            console.log('2');
            new Promise((resolve, reject) => {
                console.log('3');
                resolve();
            }).then(() => {
                console.log('4');
            }).then(() => {
                console.log('5');
            });
        }).then(() => {
            console.log('6');
        });
        new Promise((resolve, reject) => {
            console.log('7');
            resolve();
        }).then(() => {
            console.log('8');
        })
        // 输出:1 7 2 3 8 4 6 5 0