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

时间:2017-05-25 15:16:34

标签: 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); }
}

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

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

3 个答案:

答案 0 :(得分:3)

我不熟悉JavaScript语言设计讨论,但我认为这与the C# language requires的原因相同async(另见my blog)。

即:

  1. 向后兼容性。如果package.json突然在任何地方突然出现新关键字,那么使用await作为变量名称的任何现有代码都会中断。由于await是一个上下文关键字(由await激活),因此只有打算使用async作为关键字的代码才能await为关键字。
  2. 更容易解析。 await使异步代码更容易解​​析为转换器,浏览器,工具和人类。

答案 1 :(得分:1)

https://stackoverflow.com/a/41744179/1483977复制@phaux:

  

这些答案都给出了async关键字为什么的有效参数   好的,但他们都没有提到它的真正原因   已将添加到规范中。

     

原因是这是一个有效的JS pre-ES7

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

function foo() {
  return(await(42))
}
     

根据您的逻辑,foo()会返回Promise{42}或   "awaiting 42"? (返回Promise会向后突破   兼容性)

     

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

     

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

答案 2 :(得分:1)

因为在 await 函数中使用 middleware 意味着 middleware 函数不能立即返回结果(它必须等到 await 被解决)和 {{1} } 函数调用者必须等到承诺(从 middleware 函数返回)被解决。