最新版的Node.js无法使用顶层的await。

12

截至2020年1月(Node.js 13.5.0),是否仍不支持顶级await

我已经尝试了一些教程,例如这个,但仍然没有成功,总是出现相同的错误:

D:\NodeJS>node --experimental-modules test.js
(node:17724) ExperimentalWarning: The ESM module loader is experimental.
file:///D:/NodeJS/test.js:9
await test();
^^^^^

SyntaxError: Unexpected reserved word
整个文件的内容:
function test() {
}

await test();

我尝试在package.json中使用"type": "module",并将文件重命名为test.mjs,但是仍然出现相同的错误,即使使用最新的Node.js 13.5.0。

我做错了什么?


顶级等待仍然是第三阶段的提案,你认为它在Node中是实验性功能的原因是什么? - Klaycon
您所参考的文章只讨论了ES模块,而没有涉及顶级等待。 - pietrovismara
该文章描述了启用ES模块,这已经在规范中有一段时间了,而不是仍然是一个提案的顶级等待。 - Klaycon
@Klaycon,正如我所解释的那样,我确实尝试将文件重命名为*.mjs,并将type设置为module,但都没有起作用。这些东西本应该将脚本转换为ES模块。 - vitaly-t
那么你为什么要问关于顶级等待的问题?我认为你把两个不同的主题混淆了。 - pietrovismara
显示剩余3条评论
5个回答

12
根据这个问题追踪器这篇博客文章,顶层等待在Node v13.3+中可通过--harmony-top-level-await标志启用。你正在启用的模块标志仅适用于ESM模块,而非顶层等待。

那个几乎可以工作。那么这篇文章是不正确的?因为它不起作用,除非我使用 mjs 文件扩展名,或在 package.json 中设置 "type": "module" - vitaly-t
@vitaly-t 这篇文章以及规范都指出,顶级等待只能在ESM模块中使用,而不能在commonjs模块中使用,因此您必须使用mjs扩展名或"type": "module"。文章应该提到这个特性只在V8后面的标志中才能使用,但它没有。它只是说在Node中可用之前需要“一些时间”。 - Klaycon
此外,当将该标志替换为 --harmony 时,什么都不起作用。 - vitaly-t
1
啊,那是我的错误。我在其他地方读到--harmony启用了所有的harmony标志。我已经编辑了答案。 - Klaycon
4
我正在使用 Node v14.7.0,但在 node --help 中找不到任何 --harmony 标志,但有一个 --experimental-repl-await 标志可以解决我的问题。 - Saeed Ahadian
执行 node --v8-options | grep await,你就可以看到 --harmony-top-level-await - hankchiutw

4

node --experimental-repl-await可在Node REPL中使用

编辑: Node 16 REPL默认支持顶层await, 不再需要使用实验性标志


1
此外,如果您希望始终启用它而无需显式传递标志,则可以在.bashrc中导出NODE_OPTIONS ='--experimental-repl-await' - jakub.g

2

在使用node -e时:

请注意,尽管在node 14.8.0中未标记顶级await,但在执行node -enode --eval)时,输入类型默认为CJS,并且顶级await仅允许在ESM模式下使用。

要指定输入为ESM,您需要一个标志:

node --input-type=module -e 'console.log(await Promise.resolve(42))'
> 42

2
我不知道为什么,但要使用--harmony功能,您需要使用--eval(-e)或--print(-p),而不是只是启动节点,如下所示: node -e "import('./test.mjs')" --experimental-modules --input-type=module --harmony-top-level-await 文件内容:
console.log(await Promise.resolve("test"));

控制台:

node -e "import('./test.mjs')" --experimental-modules --input-type=module --harmony-top-level-await
(node:9096) ExperimentalWarning: The ESM module loader is experimental.
test


2
node 14.8.0 开始,您现在只需要 --input-type=module;其他两个参数已经默认启用。 - jakub.g

0

作为替代方案,您可以将顶层代码包装到函数中,并将其标记为async,但不等待其结果。只等待您需要等待的异步操作的结果。

这样,您就不会收到警告,但在100%的情况下不起作用,因为顶层代码可以在多个文件中。但对于大多数情况,希望能够帮助,而无需更改节点标志,因为这并不总是容易(例如,当您不运行任何节点命令并且需要提取一些节点/webpack配置时)

setupApp()

async function setupApp () {
   await action1()
   action2()
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接