浅谈Promise

一、什么是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)每次准备取出第一个宏任务来执行前,都要将所有的微任务一个一个取出来执行完成了才可以执行宏任务。

 

posted @ 2020-04-27 22:13  阿周  阅读(266)  评论(0编辑  收藏  举报