我试图将两个异步函数链接在一起,因为第一个具有条件返回参数,导致第二个参数运行或退出模块。但是,我发现在规格中找不到奇怪的行为。
async function isInLobby() {
//promise.all([chained methods here])
let exit = false;
if (someCondition) exit = true;
}
这是我的代码的一个混乱片段(你可以看到完整的范围here),只是检查一个玩家是否已经在大厅,但这是无关紧要的。
接下来我们有了这个异步功能。
async function countPlayer() {
const keyLength = await scardAsync(game);
return keyLength;
}
如果exit === true
。
我试着做
const inLobby = await isInLobby();
我希望等待结果,所以我可以使用inLobby
来有条件地运行countPlayer
,但是我收到了一个没有具体细节的类型错误。
为什么你不能await
async
函数范围之外的函数?我知道这是一个糖的承诺,所以它必须被链接到then
,但为什么在countPlayer
我可以等待另一个承诺,但在外面,我不能await
{{1 }}?
答案 0 :(得分:56)
当然总会如此:
(async () => {
await ...
})();
这使得可以使用等待的异步快速功能。它可以节省您制作非常棒的异步功能的需要! //信用Silve2611
答案 1 :(得分:44)
不支持顶级await
。标准委员会就此进行了一些讨论,例如this Github issue。
还有一个thinkpiece on Github关于为什么顶级等待是一个坏主意。具体来说,他建议如果你有这样的代码:
// data.js
const data = await fetch( '/data.json' );
export default data;
现在导入data.js
的任何文件在获取完成之前不会执行,因此现在阻止了所有模块加载。这使得很难推断app模块的顺序,因为我们习惯于同步和可预测地执行顶级Javascript。如果允许这样做,知道何时定义函数变得棘手。
我的观点是你的模块只需加载副作用就不好了。这意味着您的模块的任何消费者只需要您的模块即可获得副作用。这严重限制了您的模块的使用位置。顶级await
可能意味着您正在读取某些API或在加载时调用某些服务。相反,您应该只导出消费者可以按自己的节奏使用的异步函数。 / p>
答案 2 :(得分:6)
从Node.js 14.3.0开始,支持顶级等待。
必需标志:--experimental-top-level-await
。
答案 3 :(得分:1)
更好的方法是在代码块前面添加分号
;(async () => {
await ...
})();
这可以防止自动格式化程序(例如,vscode中的)将第一个括号移到上一行的末尾。
可以在以下示例中演示该问题:
const add = x => y => x+y
const increment = add(1)
(async () => {
await ...
})();
没有分号,它将重新设置为:
const add = x => y => x+y
const increment = add(1)(async () => {
await Promise(1)
})()
这显然是错误的,因为它将异步函数分配为y
参数,并尝试从结果中调用函数(实际上是一个奇怪的字符串'1async () => {...}'
)
答案 4 :(得分:1)
自打字稿3.8起,您可以等待顶层
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#-top-level-await
来自帖子:
这是因为以前在JavaScript中(以及其他大多数具有类似功能的语言),仅在异步函数体内允许进行等待。但是,有了顶层等待,我们可以在模块的顶层使用等待。
const response = await fetch("...");
const greeting = await response.text();
console.log(greeting);
// Make sure we're a module
export {};
请注意,这里有一个微妙之处:顶层等待仅在模块的顶层起作用,并且只有在TypeScript找到导入或导出时,文件才被视为模块。在某些基本情况下,您可能需要写出export {}作为样板,以确保这一点。
顶层等待可能不适用于您此时可能期望的所有环境。当前,仅当目标编译器选项为es2017或更高版本且模块为esnext或system时,才可以使用顶级等待。在多个环境和捆绑软件中的支持可能会受到限制,或者可能需要启用实验性支持。