简体   繁体   English

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

[英]JS async/await - why does await need async?

Why does using await need its outer function to be declared async ?为什么使用await需要将其外部函数声明为async

For example, why does this mongoose statement need the function it's in to return a promise?例如,为什么这个 mongoose 语句需要它所在的函数来返回一个承诺?

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

I see the runtime/transpiler resolving the Teams promise to it's value and async signaling it "throws" rejected promises.我看到运行时/转译器将 Teams 承诺解析为它的价值和异步信号,它“抛出”拒绝的承诺。

But try/catch "catches" those rejected promises, so why are async and await so tightly coupled?但是 try/catch “捕获”了那些被拒绝的承诺,那么为什么 async 和 await 如此紧密耦合呢?

I'm not privy to the JavaScript language design discussions, but I assume it's for the same reasons that the C# language requires async (also see my blog ).我不了解 JavaScript 语言设计的讨论,但我认为这C# 语言需要async原因相同(另请参阅我的博客)。

Namely:即:

  1. Backwards compatibility.向后兼容性。 If await was suddenly a new keyword everywhere, then any existing code using await as a variable name would break.如果await突然成为一个新关键字,那么任何使用await作为变量名的现有代码都会中断。 Since await is a contextual keyword (activated by async ), only code that intends to use await as a keyword will have await be a keyword.由于await是上下文关键字(由async激活),因此只有打算使用await作为关键字的代码才会将await设为关键字。
  2. Easier to parse.更容易解析。 async makes asynchronous code easier to parse for transpilers, browsers, tools, and humans. async使转译器、浏览器、工具和人类更容易解析异步代码。

Copied from https://stackoverflow.com/a/41744179/1483977 by @phaux:复制自https://stackoverflow.com/a/41744179/1483977 @phaux:

These answers all give valid arguments for why the async keyword is a good thing, but none of them actually mentions the real reason why it had to be added to the spec.这些答案都为为什么 async 关键字是个好东西提供了有效的论据,但没有一个真正提到必须将其添加到规范中的真正原因。

The reason is that this was a valid JS pre-ES7原因是这是一个有效的 JS 前 ES7

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

According to your logic, would foo() return Promise{42} or "awaiting 42" ?根据你的逻辑, foo()返回Promise{42}还是"awaiting 42" (returning a Promise would break backward compatibility) (返回 Promise 会破坏向后兼容性)

So the answer is: await is a regular identifier and it's only treated as a keyword inside async functions, so they have to be marked in some way.所以答案是: await是一个常规标识符,它仅被视为异步函数中的关键字,因此必须以某种方式对其进行标记。

Fun fact: the original spec proposed more lightweight function^ foo() {} for async syntax.有趣的事实:原始规范为异步语法提出了更轻量级的function^ foo() {}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM