JS async/await - 为什么等待需要异步?

Mic*_*ole 9 javascript asynchronous async-await

为什么使用await需要声明的外部函数async

例如,为什么这个mongoose语句需要它返回一个promise的函数?

async function middleware(hostname, done) {
  try {
    let team = await Teams.findOne({ hostnames: hostname.toLowerCase() }).exec();
    done(null, team);
  } catch (err) { done(err); }
}
Run Code Online (Sandbox Code Playgroud)

我看到运行时/转换器解析了团队对它的价值的承诺和异步信号,它"抛出"被拒绝的承诺.

但是try/catch"捕获"那些被拒绝的承诺,那么为什么异步并等待如此紧密耦合呢?

Mic*_*ole 7

复制自/sf/answers/2922092561/ @phaux:

这些答案都为为什么 async 关键字是一件好事提供了有效的论据,但没有一个真正提到必须将其添加到规范中的真正原因 。

原因是这是一个有效的 JS 前 ES7

function await(x) {
  return 'awaiting ' + x
}

function foo() {
  return(await(42))
}
Run Code Online (Sandbox Code Playgroud)

根据你的逻辑,会foo()返回Promise{42}还是 "awaiting 42"?(返回 Promise 会破坏向后兼容性)

所以答案是:await是一个常规标识符,它仅被视为异步函数中的关键字,因此必须以某种方式标记它们。

有趣的事实:原始规范function^ foo() {}为异步语法提出了更轻量级的建议。


Ste*_*ary 6

我并不了解JavaScript语言的设计讨论,但我认为这是出于同样的原因是 C# 语言 要求 async(见我的博客)。

即:

  1. 向后兼容。如果await突然到处都是新的关键字,那么任何await用作变量名的现有代码都会中断。由于await是一个上下文关键字(由激活的async)时,只有代码打算使用await作为关键字将具有await是关键字。
  2. 易于解析。async使异步代码更容易为编译器,浏览器,工具和人员进行解析。