顶层 await 允许在 ES 模块顶层直接使用 await,无需 async 函数包装;需满足:脚本为 type="module" 或 .mjs 文件,且运行环境支持(如现代浏览器、Node.js 14.8+)。

JavaScript 中在脚本顶层直接使用 await 是可行的,但需满足特定条件——脚本必须声明为 模块(type="module"),且运行环境支持顶层 await(现代浏览器、Node.js 14.8+ 默认启用)。这是目前最优雅、最直观的方式,无需包装函数或 Promise 链。
确保脚本是 ES 模块
顶层 await 仅在模块上下文中有效。普通 <script> 脚本不支持:
- HTML 中:用
<script type="module" src="app.js"></script> - Node.js 中:将文件后缀改为
.mjs,或在package.json中设置"type": "module" - 不推荐用
eval()或动态import()替代——会破坏静态分析和 tree-shaking
加载核心配置的典型写法
假设配置来自本地 JSON 文件或远程 API,可直接在顶层等待解析结果:
// app.js(模块脚本)
const config = await fetch('/config.json').then(r => r.json());
// 或使用 async/await 风格(更清晰)
const res = await fetch('/config.json');
const config = await res.json();
// 后续代码可直接使用 config,保证已就绪
console.log('API base:', config.apiBase);
initApp(config);
注意:若配置加载失败,脚本会直接报错中止——这反而是优点,避免静默错误导致后续逻辑异常。
立即学习“Java免费学习笔记(深入)”;
处理多配置源或降级策略
实际项目中常需 fallback 到默认配置或合并多个来源。可用 Promise.allSettled() 或条件 await:
- 优先加载远程配置,失败则回退到内置默认值:
let config;
try {
const res = await fetch('/config.json');
config = await res.json();
} catch (e) {
console.warn('Failed to load remote config, using defaults');
config = { apiBase: '/api', debug: false };
}
- 并行加载多个配置(如语言包 + 主配置),全部就绪后再继续:
const [mainCfg, i18n] = await Promise.all([
fetch('/config.json').then(r => r.json()),
fetch('/i18n/zh-CN.json').then(r => r.json())
]);
Node.js 环境下的额外注意事项
Node.js 支持顶层 await,但需注意:
- 模块内
require()仍同步,不可与顶层await混用;应统一用import()动态导入异步资源 - 若配置需从环境变量或文件系统读取,可用
fs.promises.readFile:
import { readFile } from 'fs/promises';
const configText = await readFile('./config.json', 'utf8');
const config = JSON.parse(configText);
不复杂但容易忽略:顶层 await 让配置加载成为模块初始化的自然一环,逻辑扁平、可读性强,且天然支持依赖顺序和错误传播。


















