Promise
Promise理论知识
promise本质 不是控制 异步代码的执行顺序(无法控制) , 而是控制异步代码结果处理的顺序
Promise是什么?
- 
    抽象表达 - 
        Promise是一门新的技术(ES6规范) 
- 
        Promise是JS中进行异步编程的新解决方案(旧方案:使用回调函数)  - 异步编程
            - fs 文件操作
- 数据库操作
- AJAX
- 定时器
 
 
- 异步编程
            
 
- 
        
- 
    具体表达 - 从语法上来说:Promise是一个构造函数
- 从功能上来说:promise对象用来封装一个异步操作并可以获取其==成功/失败==的结果值
 
为什么用Promise?(优点)
- 
    指定回调函数的方式更加灵活 旧的:必须在启动异步任务前指定 promise:启动异步任务 -> 返回promise对象 -> 给promise对象绑定回调函数(甚至可以再异步任务结束后指定/多个) 
- 
    支持链式调用,解决回调地狱问题 
Promise的状态
- 
    PromiseState:状态是Promise实例对象的一个属性,该属性有三个值pending 未决定的 resolved / fullfiled 成功 rejected 失败
- 
    状态的改变路径为: - 
        pending -> resolved 
- 
        pending -> rejected 
 
- 
        
- 
    说明 - 
        状态改变只有上面两种,且一个promise对象只能改变一次 
- 
        无论变为成功还是失败,都会有一个结果数据 
- 
        成功的数据一般称为value,失败的结果数据一般称为reason 
 
- 
        
Promise对象的值
- PromiseResult是- Promise实例对象的另一个属性,它保存着对象==成功或失败的==的结果。
- 
    resovle 
- reject
Promise的基本流程

https://www.bilibili.com/video/BV1GA411x7z1/?p=13&spm_id_from=pageDriver&vd_source=dde2f4dd432156027fedf9b1734ba705
如何使用Promise
API
- 
    Promise.prototype.then()- 
        定义 then方法定义在原型对象Promise.prototype上,所以promise实例可以调用then方法。
- 
        作用 为 Promise实例添加状态改变时的回调函数
- 
        返回值:返回一个新的 promise实例对象
 
- 
        
关键问题
- 
    如何改变promise对象的状态? const p = new Promise({ // 1.改变为成功fulfilled/resovled resove('OK') // 2.改变为失败rejected reject('error') // 3.改变为失败 throw '出问题了' })
- 
    一个promise对象指定多个回调函数,即多个then方法,都会执行吗? 当promise对象状态改变为回调函数对应的状态时,==都会执行==。 let p = new Promise((resove, reject) => { resove('OK') }) // 当p的状态改变为成功时,下面两个回调都会执行 // 若将resove('OK')注释掉,那么下面两个回调不会执行;因为promise对象状态没发生改变 p.then(value => console.log(value)) p.then(value => alert(value))如果是链式调用,那么会按照顺序执行 then。
- 
    改变promise状态和指定回调函数谁先谁后? 注意区分执行回调函数和指定回调函数这两个概念。 - 
          回调函数的执行肯定是在promise对象状态改变之后 
- 
          但是回调函数的指定与状态的改变顺序是不确定的。 
 - 都有可能,正常情况下是先指定回调再改变状态,但也有可能先改变状态再指定回调。
- 如何先改变状态再指定回调?
        - 在执行器中直接调用resolve(),reject()
- 延迟更长的时间才调用then()
 
- 在执行器中直接调用
 什么时候拿到数据,也就是回调函数什么时候执行? - 如果先指定回调,那么当状态发生改变时,回调函数就会调用,得到数据
- 如果先改变状态,那么指定回调时,就会执行回调,得到数据
 
- 
          
- 
    peomise.then()返回的新promise的结果状态由什么决定? then方法会返回一个新的promise对象 - 简单表达:由then中回调函数的结果决定
- 详细表达:
        - 如果抛出异常,新promise变成rejected,reason为抛出异常
- 如果返回的是非promise对象的任意值,新的promise变为resolved,value为返回值
- 如果返回的是promise对象,此promise的结果会成为新的promise的结果,该promise的状态和结果决定了新promise的结果和状态
 
 
- 
    promise如何串联多个操作任务? - promise的then()函数返回一个新的promise对象,因此可以开成.then()的链式调用
- 通过then的链式调用串联多个同步/异步任务
 
- 
    promise异常穿透? - 
        当使用promise的then链式调用时,可以在最后指定失败的回调,即catch 
- 
        前面的任何操作出了异常,都会传到最后的失败的回调中处理 不考虑顺序 
 const p = new Promise((resolve, reject) => { // resolve('ok') reject('error') }) // 直接输出最后一个捕捉错误的catch p.then((value) => { console.log('@1', value); return value }).then((value) => { console.log('@2', value); }).catch((error) => { console.log(error); })
- 
        
- 
    中断promise链 - 需求:当使用promise的then链式调用时,在中间终端,不再调用后面的回调函数
- 唯一方法:在回调函数中返回一个pendding状态的promise对象- 只有返回pendding状态的promise对象才可以终端promise链
- pendding状态的- promise对象,它的then方法无法执行
 
- 只有返回pendding状态的
 const p = new Promise((resolve, reject) => { resolve('ok') // reject('error') }) p.then((value) => { console.log('@1', value); // 返回一个pendding状态的promise return new Promise(() => { }) // 后面的then不再执行 }).then((value) => { console.log('@2', value); }).catch((error) => { console.log(error); })
自定义(手写)Promise
自己手写封装Promiese的全部功能。
async和await
Promise虽然摆脱了回调地狱,但是then的链式调⽤也会带来额外的阅读负担,并且Promise传递中间值⾮常麻烦。
async函数
- 
    async的函数返回对象是一个 promise对象- 
        返回的 promise对象的结果 由async函数执行的返回值return决定
- 
        async和then方法的返回对象规则是一样的 
 
- 
        
await函数
- 
    await右侧的表达式一般是promise对象,但也可以是其他值- 
        如果右侧表达式是 promise对象,await返回的是promise成功的值
- 
        如果右侧表达式是其他值,直接将此值作为 await的返回值
- 
        如果 await的promise失败了,就会抛出异常,需要通过try...catch处理// 将可能失败部分的代码包裹在try...catch中 try { const res3 = await p2 console.log(p2); } catch (error) { console.log(error); }
 
- 
        
注意
await必须写在async函数中,但async函数中可以没有await。
只有当await后面的异步操作执行完毕后,才会继续执行后面代码,因此保证了顺序。
同时,在错误处理方面,用async/await会比的纯回调函数更方便,只需要使用try...catch包裹代码即可。
而且,在async/await方法中在,看不到回调函数形式的代码。
