javascript-在异步函数外使用await

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

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

这是我的代码的混帐摘要(您可以在此处看到完整的范围),它只是检查玩家是否已经在大厅中,但这无关紧要。

接下来,我们有这个异步功能。

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

如果await,则不需要运行此功能。

我试着做

const inLobby = await isInLobby();

我希望这会等待结果,因此我可以使用await有条件地运行async,但是我收到没有具体细节的类型错误。

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

Sterling Archer asked 2020-01-24T06:48:15Z
3个解决方案
76 votes

当然总会有这样:

(async () => {
    await ...
})();

这使async具有快速功能,您可以在其中使用await。 它省去了制作一个很棒的异步函数的需要! //信用Silve2611

digerati-stratagies answered 2020-01-24T07:07:24Z
50 votes

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

在Github上也有一篇关于为什么等待顶级等待的想法不好的想法。 他特别建议如果您具有如下代码:

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

现在,任何导入await的文件在提取完成之前将不会执行,因此所有模块加载现在都被阻止。 由于我们习惯于以同步且可预测的方式执行顶级Javascript,因此很难确定应用模块的顺序。 如果允许这样做,那么知道何时定义函数将变得很棘手。

我的观点是,仅通过加载模块来产生副作用是不好的做法。 这意味着您的模块的任何使用者都将仅通过需要您的模块即可获得副作用。 这严重限制了模块的使用位置。 顶层await可能意味着您正在读取一些API或在加载时调用某些服务。 相反,您应该只导出供消费者按自己的节奏使用的异步函数。

Andy Ray answered 2020-01-24T07:06:59Z
2 votes

更好的方法是在代码块之前添加其他分号

;(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 () => {...}'

Viliam Simko answered 2020-01-24T07:08:02Z
translate from https://stackoverflow.com:/questions/39679505/using-await-outside-of-an-async-function