当前位置: 首页 > 知识库问答 >
问题:

因为我无法在顶层运行 await,所以我必须将其放入异步函数中 - 为什么我可以直接调用该异步函数?

蒋俊人
2023-03-14

我有一个简短的Node.js脚本,我需要另一个包并从中调用一个异步函数,然后想要打印返回值。如果我只是等待来自顶层的返回值,那么我会收到一个错误,说我只能在异步函数本身中使用await。所以很明显的方法是这样的:

async function main() {
  foo = await someOtherAsyncFunc();
  console.log(foo);
}
main()

或者:

(async function() {
  foo = await someOtherAsyncFunc();
  console.log(foo);
})();

或者:

(async () => {
  foo = await someOtherAsyncFunc();
  console.log(foo);
})();

(聊天 https://chat.stackoverflow.com/transcript/message/54186176#54186176 中归功于VLAZ)

这有效 - 但我想更多地了解其背后的原因:我习惯于无法直接从顶层使用wather。但是,我也习惯于调用一些特殊的库函数来实际“冒险”从顶层进入异步。例如,在“蟒蛇”中,请参阅“运行”。要求 await 位于异步函数中有什么意义 - 如果我可以从顶层调用任何异步函数?那么,为什么顶级联赛中也无法获得等待呢?

共有1个答案

杨晓博
2023-03-14

顶级等待过去不是一回事,但现在在ES6模块中是可能的。

顶级等待曾经不是一个东西,现在仍然不是模块之外的东西,原因之一是它可能允许语法歧义。异步和等待是有效的变量名。在模块之外。如果非模块脚本允许顶级等待,那么,除非重新编写规范(并破坏向后兼容性),否则会出现解析器无法确定await的特定实例是变量名,还是被用作等待右侧Promise解析的语法的情况。

为了避免任何歧义的可能性,解析器在解析一段代码时,本质上需要有标志来指示await是否在任何给定点作为标识符有效,或者是否作为异步语法有效,并且这两者绝不能相交。

模块 scrip 允许顶级 await(现在),因为在其中一直禁止使用 await 作为标识符,因此不存在语法歧义。

相反,使用没有任何问题。然后在顶层,因为它在任何情况下都不会导致任何歧义。

为什么它不返回一个从未执行的promise,因为它没有被等待?

promise并没有真正“执行”。它们可以被构建,或者等待实现,或者等待拒绝。如果你有一个promise,你已经有一些正在进行的代码,这些代码将(可能)最终导致一个实现值被分配给这个promise。

挂起的promise是语法上允许的值,这些值解析为promise,但不与其他地方交互。(这是有道理的-every.then.catch

正在执行

(async () => {
  foo = await someOtherAsyncFunc();
  console.log(foo);
})();

本质上是语法糖

someOtherAsyncFunc()
  .then((foo) => {
    console.log(foo);
  });

没有必要在这两者的末尾附加任何其他内容。(尽管建议在悬空promise中添加.catch,这样就不会发生未处理的拒绝)

 类似资料:
  • 问题内容: 语法的哪一部分提供了该函数应在其他线程中运行并且是非阻塞的信息? 让我们考虑一下node.js中的简单异步I / O 是什么使它在后台发生的呢?任何人都可以准确地解释它,还是可以粘贴指向一些好的资源的链接?我到处看的地方都有很多关于什么是回调的信息,但是没有人解释为什么它实际上如此工作。 这不是关于node.js的特定问题,而是关于每种编程语言中回调的一般概念。 编辑: 我提供的示例可

  • 我有一个异步函数,它调用其中的另一个异步函数。此异步函数正在返回" 你能帮我解决这个问题吗? 以下是第一个异步函数: 如你所见,我调用updateAllProducts函数,并将该值存储到一个变量调用newAllProducts. updateAllProducts是另一个异步函数。 以下是updateAllProducts的代码: 此updateAllProducts函数正在调用另一个异步函数调

  • 问题内容: 我试图将两个异步函数链接在一起,因为第一个具有条件返回参数,导致第二个运行或退出模块。但是,我发现规格中找不到奇怪的行为。 这是我的代码的混帐摘要(您可以在此处查看完整的范围),该代码只是检查玩家是否已经在大厅中,但这无关紧要。 接下来,我们有这个异步功能。 如果,则无需运行此功能。 我试着做 我希望这将等待结果,以便可以有条件地运行,但是我收到了没有具体细节的类型错误。 为什么您不能

  • 问题内容: 我的代码: 当我尝试运行这样的东西时: 我越来越: 但为什么? 我的主要目标是将令牌(从令牌中返回承诺)转换为变量。然后才执行一些操作。 问题答案: 只要其结果尚未解决,promise将始终记录未决。无论promise状态如何(已解决或仍处于待处理状态),您都必须调用promise来捕获结果: 这是为什么? 承诺只是向前的方向;您只能解决一次。a的解析值传递给其或方法。 根据Promi

  • 问题内容: 我目前正在编写JavaScript,并对 callback 感到困惑。我发现它不是内置函数…… 我现在正在阅读O’Relly JavaScript 5th Edition,它显示了示例代码,如下所示: 基本上,我想我不了解…… 的总体思路。有人可以编写示例代码来利用上面的优势吗? 问题答案: 回调非常简单又漂亮!由于AJAX调用的性质,您 不会 阻塞脚本的执行,直到您的请求结束(然后它

  • 我试图以最简单的形式理解异步等待。我想创建一个非常简单的方法,为了这个例子,添加两个数字,当然,这根本不需要处理时间,它只是在这里制定一个例子的问题。 如果我等待代码是同步运行还是异步运行?