JavaScript中Promise工作原理探究及代码执行疑问解答
你的Promise代码执行逻辑与工作机制详解
先把你的代码贴出来方便对照:
var promise = new Promise( (resolve, reject) => { var data = 'resolve'; resolve(data); console.log('promise executor'); }); setTimeout( () => { promise.then( (data) => { console.log(data); }); promise.then( (data) => { console.log(data); }); }, 2000);
第一步:Promise创建时的同步执行
当你执行new Promise(executor)的时候,传入的executor函数(就是那个带resolve、reject的箭头函数)会被立即同步执行——这就是你首先看到promise executor输出的原因。哪怕你先调用了resolve(data),后面的console.log还是会按顺序跑完,因为这都是同步代码。
这里要注意:调用resolve(data)只是把这个Promise实例的状态从pending(等待)改成了fulfilled(已完成),同时把data作为结果值存起来,但它不会中断executor里后续的同步代码,所以console.log('promise executor')该执行还是会执行。
第二步:定时器的异步任务排队
接下来的setTimeout是个宏任务,它会把里面的回调函数放到宏任务队列里,得等当前所有同步代码执行完,再等满2000毫秒后才会触发这个回调。这时候主线程已经把前面的同步代码(Promise创建、executor执行)都处理完了,所以接下来的2秒里没有输出,直到定时器触发。
第三步:Promise的then回调执行
当定时器的回调触发时,你连续调用了两次promise.then(...):
- 因为这个Promise的状态早在2秒前就被改成fulfilled了,所以这两个then的回调会被立即放进微任务队列。
- 等当前的宏任务(也就是定时器的回调函数)执行完毕,主线程会优先清空微任务队列,所以两个then的回调会依次执行,分别输出
resolve——这就是你看到后面两行输出的原因。
另外要划个重点:Promise的状态一旦改变就再也不能修改,而且同一个Promise可以被多次调用then,每次都能拿到相同的结果值,所以你两次then都能打印出resolve。
整体执行顺序总结
- 同步执行Promise构造函数,立即调用executor:
- 定义
data变量,调用resolve(data)改变Promise状态为fulfilled并存储结果 - 执行
console.log('promise executor'),输出第一行内容
- 定义
- 调用
setTimeout,将其回调加入宏任务队列,等待2秒 - 2秒后,定时器回调执行(宏任务):
- 两次调用
promise.then,两个回调被加入微任务队列
- 两次调用
- 当前宏任务执行完毕,清空微任务队列:
- 依次执行两个then的回调,分别输出
resolve
- 依次执行两个then的回调,分别输出
这样整个流程就清晰啦~
内容的提问来源于stack exchange,提问作者SasiKumar Chidambaram
相关产品推荐
相关产品推荐

