async/await 执行顺序由事件循环严格调度,同步代码立即执行,await 注册微任务,微任务在当前宏任务结束后立即执行。

async/await 的执行顺序不是靠“猜”或“经验”,而是由 JavaScript 引擎严格按事件循环(Event Loop)调度的。它表面像同步代码,底层却完全依赖 Promise 和微任务队列,每一步都可预测、可追踪。
async 函数一调用就返回 Promise,但内部同步部分立即执行
声明 async 函数时,引擎自动将其包装为返回 Promise 的函数。调用它时:
- 函数体内的同步代码(比如 console.log('1'))会立刻执行;
- 函数本身不等 await 完成,就已返回一个 pending 状态的 Promise;
- 这个 Promise 的状态,取决于函数最终 return 的值(自动 Promise.resolve)或 throw 的错误(自动 Promise.reject)。
await 不是“等待”,而是“注册微任务并暂停上下文”
遇到 await 表达式时,JavaScript 引擎不会卡住线程,而是做两件事:
- 对 await 右侧表达式求值:如果结果是 Promise,就监听它的 settled(fulfilled/rejected);
- 把 await 后面的所有语句(包括 return、throw、console.log 等)打包成一个微任务回调,加入微任务队列;
- 当前 async 函数的执行上下文被挂起,控制权交还给外层代码(比如主线程 script 或上一个宏任务)。
这个微任务会在当前宏任务结束后、下一个宏任务开始前执行——也就是在所有同步代码跑完后,立刻清空微任务队列时触发。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
执行顺序由宏任务和微任务的层级决定
看这段典型代码:
async function foo() {console.log('1');
await Promise.resolve();
console.log('2');
}
console.log('a');
foo();
console.log('b');
输出一定是:a → 1 → b → 2。原因很清晰:
- 'a' 和 'b' 是主 script 宏任务里的同步代码,最先执行;
- foo() 调用后,'1' 是同步执行的;
- await Promise.resolve() 触发微任务注册(即 '2' 对应的回调);
- 主 script 宏任务结束,引擎立即处理微任务队列,于是 '2' 输出。
错误处理本质是 Promise.catch 的自动绑定
try/catch 能捕获 await 抛出的错误,并非语法特殊,而是引擎在编译时做了等价转换:
- await somePromise 等价于 somePromise.then(value => { /* 后续代码 */ }).catch(err => { /* 进入 catch 块 */ });
- 如果没写 try/catch,这个 rejection 就变成 async 函数所返回 Promise 的拒绝原因;
- 外层可用 .catch() 或全局 unhandledrejection 事件捕获它。

















