本文一步一步深刻解读 Promise 的注册和执行过程,读懂这几段代码,Promise 的注册和执行过程你都将所向披靡,再也不话下~~~~。你就是 Promise 大神!~~。
更全解析文章:juejin.im/post/5dc028…promise
本文已代码解读的方式来学习整个过程。这里提供了四段代码,若是你都能理解清楚,正确的说出output过程,那么厉害大牛如你,Promise 的执行过程了如指掌。微信
好多大牛已经熟悉了,固然了,并非全部的人都能理解这几段代码,那么咱们就一块儿来看看吧~数据结构
本文会依次解析这几段代码,最后给出 Promise 的终极执行过程。异步
new Promise((resolve, reject) => {
console.log("外部promise");
resolve();
})
.then(() => {
console.log("外部第一个then");
return new Promise((resolve, reject) => {
console.log("内部promise");
resolve();
})
.then(() => {
console.log("内部第一个then");
})
.then(() => {
console.log("内部第二个then");
});
})
.then(() => {
console.log("外部第二个then");
});
复制代码
这个输出仍是比较简单的,外部第一个 new Promise 执行,执行完 resolve ,而后执行外部第一个 then 。外部第一个 then 方法里面 return 一个 Promise,这个return ,表明 外部的第二个 then 的执行须要等待 return 以后的结果。固然会先执行完内部两个 then 以后,再执行 外部的第二个 then ,机智如你,彻底正确。函数
output:
外部promise
外部第一个then
内部promise
内部第一个then
内部第二个then
外部第二个thenoop
new Promise((resolve, reject) => {
console.log("外部promise");
resolve();
})
.then(() => {
console.log("外部第一个then");
new Promise((resolve, reject) => {
console.log("内部promise");
resolve();
})
.then(() => {
console.log("内部第一个then");
})
.then(() => {
console.log("内部第二个then");
});
})
.then(() => {
console.log("外部第二个then");
});
复制代码
这段代码和第一段代码就相差一个 return ,然而结果确是不同的。post
那这个怎么理解呢?学习
咱们核心要看 then 的回调函数是啥时候注册的,咱们知道,事件机制是 “先注册先执行”,即数据结构中的 “队列” 的模式,first in first out。那么重点咱们来看下他们谁先注册的。ui
外部的第二个 then 的注册,须要等待 外部的第一个 then 的同步代码执行完成。 当执行内部的 new Promise 的时候,而后碰到 resolve,resolve 以后须要执行的动做是一个微任务异步执行,那么天然要先执行完同步任务,好比以下:spa
new Promise((resolve, reject) => {
resolve();
console.log(1111);
})
.then(() => {
consle.log(2222);
})
复制代码
这个代码显然优先执行 111,在执行 2222。
同理回到上面的代码,内部的 resolve 以后,固然是先执行内部的 new Promise 的第一个 then 的注册,这个 new Promise执行完成,当即同步执行后面的 .then 的注册。
然而这个内部的第二个 then 是须要第一个 then 的的执行来决定的,而第一个 then 的回调是没有执行,仅仅只是执行了同步的 .then 方法的注册,因此会进入等待状态。
这个时候,外部的第一个 then 的同步操做已经完成了,而后开始注册外部的第二个 then,此时外部的同步任务也都完成了。同步操做完成以后,那么开始执行微任务,咱们发现 内部的第一个 then 是优先于外部的第二个 then 的注册,因此会执行完内部的第一个 then 以后,而后注册内部的第二个 then ,而后执行外部的第二个 then ,而后再执行内部的第二个 then。
output:
外部promise
外部第一个then
内部promise
内部第一个then
外部第二个then
内部第二个then
new Promise((resolve, reject) => {
console.log("外部promise");
resolve();
})
.then(() => {
console.log("外部第一个then");
let p = new Promise((resolve, reject) => {
console.log("内部promise");
resolve();
})
p.then(() => {
console.log("内部第一个then");
})
p.then(() => {
console.log("内部第二个then");
});
})
.then(() => {
console.log("外部第二个then");
});
复制代码
这段代码的差别,就是内部的 Promise 的代码的写法变了,再也不是链式调用。
这里怎么理解呢?
这里在执行内部的 new Promise 的 resolve 执行完成以后,new Promise 以后的两个同步 p.then 是两个执行代码语句,都是同步执行,天然是会同步注册完。
两种方式的最主要的区别是:
因此这里的代码执行就比较清晰了,内部都执行完成以后(由于都优先于外部的第二个 then 的注册),再执行外部的第二个 then :
output:
外部promise
外部第一个then
内部promise
内部第一个then
内部第二个then
外部第二个then
let p = new Promise((resolve, reject) => {
console.log("外部promise");
resolve();
})
p.then(() => {
console.log("外部第一个then");
new Promise((resolve, reject) => {
console.log("内部promise");
resolve();
})
.then(() => {
console.log("内部第一个then");
})
.then(() => {
console.log("内部第二个then");
});
})
p.then(() => {
console.log("外部第二个then");
});
复制代码
这段代码中,外部的注册采用了非链式调用的写法,根据上面的讲解,咱们知道了外部代码的 p.then 是并列同步注册的。因此代码在内部的 new Promise 执行完,p.then 就都同步注册完了。
内部的第一个 then 注册以后,就开始执行外部的第二个 then 了(外部的第二个 then 和 外部的第一个 then 都是同步注册完了)。而后再依次执行内部的第一个 then ,内部的第二个 then。
output:
外部promise
外部第一个then
内部promise
外部第二个then
内部第一个then
内部第二个then
我相信,若是能看懂上面的四段代码以后,对 Promise 的执行和注册很是了解了。
若是仍是不太懂,麻烦多看几遍,相信你必定能懂~~~~~~~~
核心思想:
Promise 的 then 的 注册 和 执行 是分离的。
注册 : 是彻底遵循 JS 的代码的执行过程。
执行 : 先 同步,再 微任务 ,再 宏观任务。
遵循 event loop的原理,Promise 控制了 then 的注册时机。
只有分开理解上述,才能真正理解它们的执行顺序~~~~~~~~~~~~~~~~
最后出一道题:
new Promise((resolve, reject) => {
console.log("外部promise");
resolve();
})
.then(() => {
console.log("外部第一个then");
new Promise((resolve, reject) => {
console.log("内部promise");
resolve();
})
.then(() => {
console.log("内部第一个then");
})
.then(() => {
console.log("内部第二个then");
});
return new Promise((resolve, reject) => {
console.log("内部promise2");
resolve();
})
.then(() => {
console.log("内部第一个then2");
})
.then(() => {
console.log("内部第二个then2");
});
})
.then(() => {
console.log("外部第二个then");
});
复制代码
你能知道输出结果,且能解释清楚吗?
若是你以为这篇内容对你有价值,请点赞,并关注咱们的官网和咱们的微信公众号(WecTeam),每周都有优质文章推送: