一、什么是Promise?
(1)Promise时JS中进行异步编程的新的解决方案。(旧的是回调函数)
(2)从语法上看,Promise是一个构造函数。
(3)从功能上来说,Promise对象用来封装一个异步操作并可以获取其结果。
二、Promise的状态
1.Promise一共有三种状态,pending(准备中)、resolved(成功)、rejected(失败)。
2.Promise只有两种状态改变:
(1)pending变为resolved
(2)pending变为rejected
3.说明:
(1)一个Promise对象只有这两种状态变化,且只能改变一次,不可逆的。
(2)不管成功还是失败,都会有一个结果数据。
(3)成功的结果一般称为value,失败的结果一般称为reason。
三、基本使用
const p = new Promise (( resolve , reject ) => { //异步操作 }); p.then( value => { //成功 }, reason => { //失败 } )
四、两种常见方法
1.Promise.All()
//创建几个Promise对象 const p1 = new Promise ( ... ); const p2 = new Promise ( ... ); ... Promise.all([p1,p2 ...]).then(values=>{})
注意:(1)返回的values是按着前面all的参数顺序的数组。
(2)只有全部成功才返回,有一个失败则全部不返回。
2.Promise.race()
使用同all一样,但是执行多个异步操作时,只保留第一个执行完成的结果,其他的还是会执行完,但是不返回结果。相当于比赛。
五、Promise和旧的异步编程解决方案相比,为什么要使用Promise?
(1)旧的:必须在启动异步任务前指定。而Promise是先启动异步任务,返回Promise对象,再给Promise绑定回调函数。
(2)Promise支持链式调用,可以解决回调地狱问题。
六、那么什么是回调地狱呢?
回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调函数的条件。
注意:回调地狱的终极解决方案是:async/await
七、什么是Promise的异常传递?
(1)当使用Promise的then链式调用时,可以在最后指定失败的回调。
(2)前面任何操作出了异常,都会传到最后失败的回调函数中处理。
注意:中间的所有回调函数都有执行,只是出了异常的那一环开始,后面的回调都会默认执行失败的回调函数,然后抛出异常,到下一环再执行失败,抛出异常,直到最后。
例如:
new Promise ((resolove,reject) => { reject(); //失败 }).then( value =>{}, //不执行 // 如果这里不写则默认为 reason => { throw reason } ).then( //与上面相同 ).catch((null,reason) => { //这里来处理失败 });
八、如何中断Promise链?
1.什么是中断Promise链?
当使用Promise的then链式调用时,在中间中断,并且不再调用后面的回调函数了。
2.方法:在回调函数中返回一个状态为pending的Promise对象即可。
九、async/await
1.async函数:
(1)函数的返回值是一个Promise对象。
(2)Promise对象的结果有async函数执行的返回值绝定。
2.await表达式
(1)await右侧的表达式一般是Promise对象,也可以是其他的值(一般的表达式)。
(2)如果表达式是Promise对象,await返回的是Promise的成功值,不返回失败的值。
(3)如果表达式是其他,则该值将直接作为await的返回值。
3.注意:
(1)await必须写在async函数中,但async函数中可以没有await。
(2)如果await的Promise返回失败,会抛出异常,可以通过try...catch来捕获异常。
十、小谈宏任务和微任务
1.概念:JS中用来存储执行回调函数的队列包含的两个不同特定的队列。
2.宏队列:用来保存待执行的宏任务(回调)
例如:定时器回调、DOM事件回调、ajax回调
3.微队列:用来保存待执行的微任务(回调)
例如:Promise的回调(then里的)、MutationObserver的回调
4.JS执行时会区别这两个队列
(1)JS引擎首先必须执行所有的初始化同步任务代码
(2)每次准备取出第一个宏任务来执行前,都要将所有的微任务一个一个取出来执行完成了才可以执行宏任务。