在异步函数之外使用 wait

我试图将两个异步函数链接在一起,因为第一个函数有一个条件返回参数,导致第二个函数要么运行,要么退出模块。然而,我发现了一些奇怪的行为,我在规格中找不到。

async function isInLobby() {
//promise.all([chained methods here])
let exit = false;
if (someCondition) exit = true;
}

This is a bastardized snippet of my code (you can see the full scope 给你), that simply checks if a player if already in a lobby, but that's irrelevant.

接下来我们有这个异步函数。

async function countPlayer() {
const keyLength = await scardAsync(game);
return keyLength;
}

如果 exit === true

我尽力了

const inLobby = await isInLobby();

我希望这将等待结果,所以我可以使用 inLobby有条件地运行 countPlayer,但是我收到了一个没有具体细节的打字错误。

为什么你不能 await一个 async函数的范围之外的功能?我知道这是一个糖的承诺,所以它必须链接到 then但为什么在 countPlayer我可以等待另一个承诺,但在外面,我不能 await isInLobby

211813 次浏览

不支持顶级 await。标准委员会对此进行了一些讨论,例如 这个 Github 问题

还有一个关于为什么高层等待是一个坏主意的 Github 上的思想文章。他特别建议如果你有这样的代码:

// data.js
const data = await fetch( '/data.json' );
export default data;

现在,导入 data.js任何文件在提取完成之前不会执行,因此现在阻塞了所有模块加载。这使得我们很难推断应用程序模块的顺序,因为我们习惯于顶级 Javascript 同步和可预测地执行。如果允许这样做,那么知道函数何时定义就变得很棘手了。

我的观点是,对于您的模块来说,仅仅加载它就会产生副作用是不好的做法。这意味着您的模块的任何使用者只需要使用您的模块即可获得副作用。这严重限制了模块的使用范围。顶级的 await可能意味着您正在读取某个 API 或调用 加载时间。上的某个服务,相反,您应该只导出使用者可以按照自己的速度使用的异步函数。

当然,总是存在这样的情况:

(async () => {
await ...


// all of the script....


})();
// nothing else

这使得一个快速的异步函数,您可以在其中使用 wait。它节省了你的需要,使一个异步函数,这是伟大的!//信贷 Silve2611

你可以从3.8开始做顶级等待
Https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#-top-level-await
From the post:
这是因为以前在 JavaScript (以及大多数具有类似特性的其他语言)中,wait 只能在异步函数体中使用。但是,对于顶级等待,我们可以在模块的顶级使用等待。

const response = await fetch("...");
const greeting = await response.text();
console.log(greeting);


// Make sure we're a module
export {};

注意,这里有一个微妙之处: 顶层等待只能在模块的顶层工作,而且只有当 TypeScript 找到导入或导出时,文件才被认为是模块。在某些基本情况下,您可能需要将导出{}作为一些样板来编写,以确保这一点。

顶级等待可能不适用于您此时可能期望的所有环境。目前,只有当目标编译器选项为 es2017或更高版本,并且模块为 esnext 或 system 时,才能使用 top level wait。在几个环境和捆绑包中的支持可能是有限的,或者可能需要启用实验性支持。

As of Node.js 14.3.0, the top-level await is supported with a flag:

--experimental-top-level-await

到 Node.js 16.12.0/17.0.0时,不需要标志。

详情: https://v8.dev/features/top-level-await