图解一道刁钻的Promise题目
图解一道刁钻的Promise题目
YuXiang1.题目
1 | Promise.resolve().then(() => { |
2.考察点
2.1 Promise 的微任务队列
- Promise 的回调(then、catch、finally)会被放入微任务队列
- 微任务队列在当前宏任务执行完毕后立即执行,直至清空微任务队列中的所有任务
2.2 事件循环(Event Loop)
- JavaScript 是单线程的,通过事件循环机制处理异步任务
- 事件循环分为宏任务(如 setTimeout、setInterval)和微任务(如 Promise)
- 微任务的优先级高于宏任务。
2.3 Promise 的链式调用
- then 方法返回一个新的 Promise,实现链式调用
- 如果 then 的回调返回一个 Promise,后续的 then 会等待该 Promise 完成后再执行。
2.4 Promise.resolve 的作用
Promise.resolve(value)
这个方法是 ES6 中的Promise提供的一个静态方法, 返回一个 Promise 对象。返回Promise对象处于什么状态取决入传入的参数.
- 如果这个值是一个 Promise,将返回一个 Promise
- 如果这个值是一个 thenable,返回的 Promise 会使用这个thenable,并且取它的最终状态
- 否则返回的 promise 将以此值完成,即用此值执行去 resolve()方法
简单实现一下 resolve 方法
1 | class Promise { |
3.解题方案
将提供2种解题方案
3.1执行过程分析
同步代码执行 :
- 两个 Promise.resolve() 会立即执行,分别将它们的 then 回调放入微任务队列。
微任务队列的执行 :
第一个微任务(第一个 Promise 链的第一个 then):
打印 0。
返回
Promise.resolve(4)
,这会创建一个新的 Promise,并将其放入微任务队列。
第二个微任务(第二个 Promise 链的第一个 then):
打印 1。
返回 undefined(默认返回值),将下一个 then 回调放入微任务队列。
第三个微任务(第二个 Promise 链的第二个 then):
打印 2。
返回 undefined,将下一个 then 回调放入微任务队列。
第四个微任务(第二个 Promise 链的第三个 then):
打印 3。
返回 undefined,将下一个 then 回调放入微任务队列。
第五个微任务(第一个 Promise 链的第二个 then):
- 等待 Promise.resolve(4) 完成,打印 4。
第六个微任务(第二个 Promise 链的第四个 then):
打印 5。
返回 undefined,将下一个 then 回调放入微任务队列。
第七个微任务(第二个 Promise 链的第五个 then):
- 打印 6。
3.2任务队列图
输出 | 微任务队列 |
---|---|
[0,1] | |
0 | [1,then] |
1 | [then,2] |
[2,resolve] | |
2 | [resolve,3] |
[3,4] | |
3 | [4,5] |
4 | [5,6] |
5 | [6] |
6 | [] |
3.3转化代码
结合上边的resolve
方法将第一段Promise修改一下
1 | Promise.resolve().then(() => { |
此时题目变成了
1 | Promise.resolve().then(() => { |
看到这,我想大部分同学应该已经恍然大悟了,原来如此。