顶级 await 仅适用于 ES 模块,需通过 type="module"、.mjs 后缀或 package.json 中 "type": "module" 启用;它允许模块顶层直接 await,按序串行执行,阻塞导入者,错误须在模块内 try/catch 捕获。
顶级 await 只能在 ES 模块(ESM)中使用,不能在 CommonJS 或脚本(
)环境中直接使用;它允许在模块顶层直接写
表达式,而无需包裹在 async 函数内。
必须在 ESM 模块上下文中启用
顶级 await 依赖模块的异步初始化语义。只有当模块以
加载,或文件后缀为
(或被
中
标识),才能被 JavaScript 引擎识别为 ESM 模块并启用顶级 await。
浏览器中需用
引入
Node.js 中需满足以下任一条件:
后缀、
含
、或通过
执行字符串代码
若用
加载或
(且未启用模块模式),会报错
模块执行顺序受 await 影响
含顶级 await 的模块会暂停自身执行,等待 Promise 解决后才继续,并阻塞其所有静态导入者(即依赖它的模块)。这改变了传统模块同步加载的时序模型。
假设模块 A
模块 B,而 B 有顶级
,则 A 的执行会等到 B 的 Promise 完成后才开始
多个顶级 await 会按书写顺序串行执行,但不会自动并行(如需并发,应显式用
)
注意:模块缓存仍生效——同一模块多次 import 不会重复执行顶级代码,包括 await 部分
不能用于动态 import() 的返回值解构
顶级 await 作用于表达式,而非声明。虽然可
,但不能在顶层直接解构其默认导出或命名导出:
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
立即学习
“
Java免费学习笔记(深入)
”;
✅ 合法:
❌ 非法:
(解构不是简单赋值,属于声明语句)
✅ 替代写法:
错误处理需显式捕获
顶级 await 抛出的异常会导致整个模块实例化失败,且无法被外部 try/catch 捕获(因 import 是声明式行为)。必须在模块内部用
处理。
例如:
若未捕获,模块状态变为
,所有依赖它的
语句都会拒绝 Promise,抛出异常
Node.js 中可通过
监听,但不推荐作为兜底方案
不复杂但容易忽略:它让模块具备“异步初始化”能力,但也要求开发者更谨慎地设计依赖链和错误恢复逻辑。
awaittype="module".mjspackage.json"type": "module".mjspackage.json"type": "module"node --input-type=modulerequire()node index.jsSyntaxError: await is only valid in async functions and the top level bodies of modulesimportawait fetch(...)Promise.all()await import('./foo.js')const mod = await import('./utils.js');const { helper } = await import('./utils.js');const mod = await import('./utils.js'); const { helper } = mod;try...catchtry { const data = await fetch('/api').then(r => r.json()); } catch (e) { console.error('初始化失败', e); }"errored"importprocess.on('unhandledRejection')