在异步函数之外使用 await

2022-08-30 05:20:45

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

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;
}

如果 .,则此函数不需要运行。exit === true

我试图做

const inLobby = await isInLobby();

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

为什么不能在函数范围之外使用函数?我知道这是一个糖的承诺,所以它必须被束缚起来,但为什么在我可以等待另一个承诺,但在外面,我不能?awaitasyncthencountPlayerawaitisInLobby


答案 1

当然,总有这样:

(async () => {
    await ...

    // all of the script.... 

})();
// nothing else

这使得一个带有异步的快速功能,您可以在其中使用 await。它节省了您制作异步函数的需要,这很棒!学分 Silve2611


答案 2

不支持顶级。标准委员会有一些关于为什么会这样讨论,比如这个Github问题await

Github上还有一个关于为什么顶级等待是一个坏主意的思想。具体来说,他建议,如果你有这样的代码:

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

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

我的观点是,你的模块仅仅通过加载它就有副作用是不好的做法。这意味着您的模块的任何消费者只需需要您的模块即可获得副作用。这严重限制了模块的使用位置。顶级可能意味着您正在从某个 API 读取数据或在加载时调用某个服务。相反,您应该只导出使用者可以按照自己的节奏使用的异步函数。await