Promise 理解
Promise 执行顺序总结分析
代码分析
javascript
const p1 = Promise.resolve(1);
const p2 = new Promise(resolve => resolve(p1));
p2.then(res => console.log(2));
p1.then(() => console.log(1)).then(() => console.log(4));
console.log(3);执行顺序
输出结果:3, 1, 4, 2
详细执行过程
1. Promise 创建阶段
- 创建 p1:
Promise.resolve(1)创建一个已解决(fulfilled)的 Promise,值为 1 - 创建
p2:调用Promise.resolve(),传入一个 executor 函数resolve => resolve(p1)
2. p2 构造过程详解
当执行 p2 的构造函数时:
- 立即执行传入的 executor:
resolve => resolve(p1) - 调用内部的
resolve函数,参数为p1 - 进入
resolvePromise函数处理:javascriptif (value instanceof Promise) { // value 是 p1 value.then(resolve, reject); // 关键:建立依赖关系 return; } - 由于
p1已经是 fulfilled 状态,p1.then(resolve, reject)会将p2的 resolve/reject 函数加入微任务队列
3. 回调注册顺序
按时间顺序注册的回调:
p1.then(p2_resolve, p2_reject)- 来自resolvePromise内部调用p1.then(() => console.log(1))- 显式注册到p1.then(() => console.log(4))- 链式 Promise 的回调p2.then(res => console.log(2))- 注册到p2
4. 微任务队列执行
微任务执行顺序:
p2_resolve- 使p2变为 fulfilled 状态,触发p2.then回调注册() => console.log(1)-p1的第一个回调() => console.log(4)- 链式 Promise 回调() => console.log(2)-p2的回调(在步骤 1 中触发注册)
5. 最终输出
3 // 同步代码立即执行
1 // p1 的第一个回调
4 // 链式 Promise 回调
2 // p2 的回调核心要点
- Promise 解析机制:当一个 Promise 被 resolve 为另一个 Promise 时,会通过
then方法建立依赖关系 - 微任务队列:Promise 回调都放入微任务队列,按注册顺序执行
- 状态传播:
p2的状态依赖于p1,只有p1完成后p2才能变为 fulfilled - 执行时机:虽然
p2的 resolve 函数注册最早,但p2.then的回调是在p2状态改变后才注册的,所以执行较晚
这个例子完美展示了 Promise 的异步特性、状态传播机制以及微任务队列的执行顺序。
拓展
js
const p1 = Promise.resolve(1);
const p2 = new Promise(resolve => resolve(p1));
p2.then(res => console.log(2));
p1.then(() => console.log(1)).then(() => console.log(4));
console.log(3);
// 对比下面的代码 输出结果有何不同,理解什么是promise吸收
const p3 = Promise.resolve(1);
const p4 = Promise.resolve(resolve => resolve(p3));
p4.then(res => console.log(2));
p3.then(() => console.log(1)).then(() => console.log(4));
console.log(3);