await 后代码以微任务形式异步执行,不阻塞事件循环,仍共享原 async 函数作用域与 this 绑定,支持跨 await 的 try/catch,其执行时机受微任务队列调度影响。

await 后的代码不会在原调用栈中同步执行,而是被包装进一个微任务(microtask),等当前同步代码执行完、本轮事件循环的微任务队列清空时才执行。
await 实际触发的是 Promise.then 的微任务调度
当 async 函数遇到 await 时,引擎会将 await 后面的表达式转为 Promise(若还不是),然后调用其 Promise.then 注册回调。这个回调被放入微任务队列,而非立即执行。
- 即使 await 的 Promise 已处于 fulfilled 状态(比如
await Promise.resolve(42)),后续语句仍要等到当前同步任务结束、微任务队列轮到它时才运行 - 这和直接写
Promise.resolve().then(...)行为一致,不是“立刻继续”,而是“尽快但异步” - 因此,在 await 之后的代码里访问变量、调用函数,其执行时机与同步代码有明确隔离
await 后的代码运行在新的执行上下文,但仍在同一 async 函数作用域内
await 暂停的是当前 async 函数的执行,不退出函数作用域。恢复后,仍使用原来的词法环境(LexicalEnvironment)和 this 值(除非被显式改变)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 局部变量、参数、闭包捕获的外部变量都保持可访问,不需要额外绑定或保存
- this 的值取决于 async 函数如何被调用(如作为对象方法、箭头函数嵌套等),await 不影响 this 绑定逻辑
- 函数内部的 try/catch 可跨越 await 捕获后续 Promise reject,因为整个 async 函数体被编译为单个 Promise 链处理逻辑
执行顺序受微任务队列与宏任务交互影响
await 解析完成后,其后续代码排队等待微任务执行,此时可能被同轮循环中的其他微任务(如另一个 Promise.then、queueMicrotask)穿插。
- 多个 await 连续出现时,每个 await 都会生成一个微任务入口,按顺序排队,但中间可能插入其他微任务
- 如果 await 后紧跟 setTimeout 或事件监听器回调,后者属于宏任务,一定晚于所有当前微任务执行
- 注意:await 并不阻塞事件循环,只是暂停函数体执行;JS 引擎可继续处理其他任务(如渲染、I/O 回调)
调试时看到的“断点连续”是工具优化,非真实同步执行
现代 DevTools 在 async/await 上做了执行流可视化增强,让 await 前后断点看起来像同步单步,但这只是 UI 映射。实际堆栈已切换,且中间可能有其他微任务运行。
- 在 debugger 中单步跳过 await,控制台显示的调用栈顶部仍是原 async 函数名,但底层执行上下文已重建
- 若需确认真实执行时机,可在 await 后加
console.log('after await'),并对比queueMicrotask(() => console.log('microtask'))输出顺序 - V8 的 async 函数实现本质是状态机 + Promise 链,每次 await 对应一次状态跃迁和微任务入队
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










