14.3.0中通过--experimental-top-level-await
和后来的--harmony-top-level-await
将顶级等待支持添加到Node.js中。
问题
如果当前Node.js运行时支持,我需要在ESM脚本文件中使用顶级等待。此外,我需要设置一个布尔标志,以指示在顶级成功地等待了promise。
我的意思是:
let topLevelAwaitEnabled;
try {
await Promise.resolve(); // replaced with an actual promise
topLevelAwaitEnabled = true;
} catch (ignored) {
topLevelAwaitEnabled = false;
}
console.log(topLevelAwaitEnabled);
// carry on with the rest of the application, regardless of success or failure
// at some point, topLevelAwaitEnabled is checked to conditionally execute some code
如果启用了最高级别的等待支持,则会成功但是,如果不支持,这将在解析期间导致以下错误,并且无法在runtime中使用try
/catch
:捕获
$ node test.js...test.js:3
await Promise.resolve(); // replaced with an actual promise
^^^^^
SyntaxError: await is only valid in async function
因此,问题是:如果得到支持,我如何使用顶级等待,而不会与不支持顶级等待的Node.js运行时(要么没有指定CLI标志,要么根本没有运行时支持(产生不兼容问题?
如果答案是"否";这是不可能的";,我想解释一下为什么这是不可能的。
在我实际提交XY问题的情况下,根本问题是我需要一个顶级动态导入。
注意:我很清楚,出于各种原因,不建议使用顶级等待,但它对我的应用程序的特定功能至关重要,不会给我的用例带来任何问题。替代方案可能不够。
尝试次数
我尝试了以下方法,但没有成功:
eval
:我尝试用eval("await Promise.resolve()")
替换等待行,希望在当前上下文中评估代码。不幸的是,即使支持顶级等待,这也会导致同样的错误,因为它似乎没有继承当前上下文vm.compileFunction
:与eval()
问题相同,不支持顶级等待vm.SourceTextModule
:评估是异步的,需要在顶层等待,以检查它是否受支持。。。它是一个掣子22- 基于
process.version
和process.execArgv
的await
的条件执行:解析过程中的错误-它从未实际执行过代码,因此排除了条件执行
据我所知,这是不可能的,因为解析器只会出错。编译器将无法理解await
指令,也无法完成其循环。这可能类似于使用一个根本无法识别的关键字。
最接近的方法是使用匿名函数。
似乎您可以像process.version
一样检查运行时使用的节点的版本,然后您也可以使用process.argv
来检查启动进程时传入的任何标志。
使用以上方法,您可以首先检查正在使用的节点的版本,然后如果相关,您可以检查所需的标志。
关于检查CLI参数的节点文档。
(async()=>{await promise})()