执行上下文是javascript同步代码运行的环境容器,promise微任务在当前上下文清空后由事件循环触发;async/await中await后的代码被包装为微任务。

执行上下文是 JavaScript 代码运行的“环境容器”,而 Promise 的微任务调度,是在这个容器执行完毕后才被事件循环触发的。两者不是并列关系,而是先后协作:执行上下文负责同步代码和函数调用的管理;Promise 的 then/catch/finally 回调 则在当前执行上下文清空后,作为微任务被统一处理。
执行上下文决定“谁在运行”,不决定“谁先异步执行”
每当一段代码(全局脚本、函数调用、eval)开始执行,JS 引擎就会创建一个执行上下文,并压入调用栈。它包含变量环境、词法环境和 this 绑定等信息。同步代码就在这个上下文中逐行执行——包括 Promise 构造器里的 executor 函数(resolve() 和 console.log 都是同步的)。但 then() 方法本身只是注册回调,并不执行回调,它的回调会被推迟到微任务队列中。
Promise.then 是微任务,但注册发生在当前执行上下文中
调用 p.then(...) 这个动作是同步的,它立即返回一个新的 pending Promise,并把回调函数记入内部微任务队列(PromiseJob Queue)。关键点在于:
- 回调函数不会在
then()调用时执行,哪怕 Promise 已经是 fulfilled 状态 - 它必须等到当前宏任务(比如整个 script 标签或 setTimeout 回调)的执行上下文完全退出、调用栈为空后,才由事件循环取出并执行
- 多个
then()注册的回调,会按注册顺序排队进入微任务队列,且一次性全部清空
执行上下文结束 → 微任务清空 → 下一个宏任务
这是事件循环的标准流程。例如:
- 全局脚本执行(一个宏任务):创建 promise、调用
then、打印同步日志 → 执行上下文逐步弹出 - 上下文清空后,引擎检查微任务队列:发现已 resolve 的 Promise 对应的
then回调 → 立即执行 - 微任务队列变空 → 事件循环从宏任务队列取下一个(如 setTimeout)→ 新的执行上下文被创建
async/await 本质也是基于执行上下文 + 微任务
await 并不是语法糖的“暂停”,而是让出当前执行上下文,并把后续代码包装成微任务。比如:
-
await promise2()执行完后,console.log('async1 inner')不会立刻运行 - 它被放入微任务队列,等待当前宏任务(含 asyncFun 的初始部分)结束后再执行
- 这说明:async 函数体内的同步代码属于当前执行上下文;await 后的代码,则交由微任务机制接管
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











