You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。

整体执行顺序总结

  1. 同步执行Promise构造函数,立即调用executor:
    • 定义data变量,调用resolve(data)改变Promise状态为fulfilled并存储结果
    • 执行console.log('promise executor'),输出第一行内容
  2. 调用setTimeout,将其回调加入宏任务队列,等待2秒
  3. 2秒后,定时器回调执行(宏任务):
    • 两次调用promise.then,两个回调被加入微任务队列
  4. 当前宏任务执行完毕,清空微任务队列:
    • 依次执行两个then的回调,分别输出resolve

这样整个流程就清晰啦~

内容的提问来源于stack exchange,提问作者SasiKumar Chidambaram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:52:02