顶层await是es2022正式标准,允许在es模块顶层直接使用await,无需async函数包裹;需.mjs文件或"type":"module",支持node.js 14.8+及现代浏览器,适用于配置加载、条件导入等前置异步初始化场景。

Top-level await 允许你在 ES 模块的顶层(即模块作用域,非函数内)直接使用 await,无需包裹在 async function 中。它从 ES2022(ECMAScript 13)起成为正式标准,且现代浏览器和 Node.js(v14.8+ 默认启用,v16+ 稳定支持)均已支持。
必须在 ES 模块环境中使用
Top-level await 只在 ES 模块(.mjs 文件或 package.json 中 type: "module")中有效。CommonJS(require / module.exports)不支持,且 script 标签需显式声明 type="module":
- Node.js:确保文件后缀为
.mjs,或package.json含"type": "module" - 浏览器:
<script type="module" src="app.mjs"></script> - 不支持
<script></script>普通脚本或require()加载的模块
基本用法:直接 await Promise
你可以在模块顶层写 await 表达式,模块会暂停执行,直到 Promise 解决,再继续后续语句:
// config.mjs
const response = await fetch('/api/config.json');
const config = await response.json();
export const API_URL = config.baseUrl;
export const TIMEOUT = config.timeout || 5000;
注意:该模块自身会变成一个异步模块,所有依赖它的模块也会被“异步化”——即导入者需等待它完成初始化。
常见适用场景
Top-level await 特别适合一次性、前置的异步初始化任务:
- 动态配置加载:如上例,从远程或环境获取配置后再导出常量
- 权限/认证检查:等待登录态验证通过再暴露业务逻辑
- 资源预加载:await 图片、字体、WebAssembly 实例等再初始化 UI
-
条件性导入:结合
import()动态导入并 await 初始化结果
注意事项与限制
虽然方便,但需谨慎使用:
- 模块加载是阻塞式的:一个 top-level await 卡住,整个模块及其依赖链都会延迟执行
- 不能用于循环或条件分支内部(语法错误),只能出现在模块顶层作用域
- 不能和
var声明混用(因提升机制冲突),推荐统一用const或let - 调试时注意:Chrome DevTools 的“Pause on caught exceptions”可能中断 await 链,需留意
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











