Node.js+Express中无async函数直接用await为何可行?
为什么Node.js ES模块顶层可以直接使用await而不需要包裹async函数?
我用Node.js和Express开发项目时,在app.js里发现一个奇怪的现象——没有把代码放在async函数里,却直接用了await,代码居然还能正常运行。我的逻辑是判断文件是否存在,不存在就创建,await就用在创建文件的步骤里,代码如下:
import express from "express"; import path from "path"; import fs from "fs"; import { fileURLToPath } from "url"; const app = express(); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); const filePath = path.join(dirname, "../files/products.json"); const exist = fs.existsSync(filePath); if (!exist) await fs.promises.writeFile(filePath, JSON.stringify([]));
想知道这背后的原理是什么?
原理解释
这是因为Node.js支持ES模块的顶层await特性,简单来说就是在ES模块(使用import/export语法的模块)的顶层作用域里,可以直接使用await关键字,不需要把它包裹在async函数中。
具体细节:
- 当你在ES模块顶层使用
await时,这个模块会变成"异步模块",它的加载过程会暂停,直到await后的Promise完成。其他依赖这个模块的代码,也会等待该模块加载完成后再执行。 - 你的代码用了
import语法,属于ES模块,完全符合顶层await的使用条件。但如果是CommonJS模块(使用require语法),则不支持这个特性,直接用顶层await会报错。 - 你代码里的
fs.promises.writeFile返回的是一个Promise,顶层await会等待这个Promise执行完成,确保文件创建成功后再继续执行后续模块代码,所以你的逻辑能正常运行,不会出现未处理Promise或异步顺序问题。
内容的提问来源于stack exchange,提问作者Gabriel Godoy
相关产品推荐
相关产品推荐

