JS Promises:为什么 await 必须在异步函数中?

JS Promises: Why does await have to be inside an async function?

假设我有以下代码:

new Promise(res => res(1))
.then(val => console.log(val))

我可以像这样用 async/await 实现同样的事情:

let func = async () => {
  let val = await new Promise(res => res(1))
  console.log (val)
}
func()

我将 async/await 代码放在函数中只是因为您必须在异步函数中才能使用 await.

我想知道的:为什么要强制执行此规则?只是这样做会有什么问题

let val = await new Promise(res => res(1))
console.log (val)

await 导致当前作用域暂停执行的原因,因此强制您将 async/await 代码放在异步函数的特殊作用域内可以防止 JS 暂停执行您的所有其他代码?

async 函数是另一种函数。它总是 return 的承诺。在它命中的第一个 await 点,函数执行被暂停,异步函数 return 承诺并且调用者获得承诺并继续执行接下来的任何代码。

此外,async 函数自动将其函数体包装在 try/catch 中,这样任何异常,无论是同步的还是未处理的来自 await 的被拒绝的承诺都会被 [=自动捕获=10=] 函数并变成拒绝他们自动 return.

的承诺

并且,当您 return 来自 async 函数的值时,该 return 值成为它 return 的承诺的解析值。

What I Want To Know: Why is this rule enforced? What would be the problem with just doing...

一个 async 函数有许多常规函数没有的行为,JS 解释器想提前知道它是哪种类型的函数,以便它可以使用正确的类型正确地执行它行为。

我想解释器可能在编译函数体时发现它包含 await 并自动赋予周围函数一个 async 行为,但这不是很声明性的和简单地添加或删除一个 await 可能会完全改变函数的工作方式。这只是我的猜测,但语言设计者决定强制以这种方式声明 async 函数,而不是根据函数体的内容推断其行为要好得多。

这里的大局是理解 async 函数的工作方式不同:

  1. 永远return是一个承诺
  2. 自动捕获异常或拒绝等待并将它们变成拒绝
  3. 等待时暂停函数执行
  4. 将 returned 值转换为 promise 的解析值 returns
  5. 将显式returned 承诺链接到异步returned 承诺。

而且,如果在声明中使用 async 关键字而不是从函数体中推断出单独的行为,那么语言会更清晰、更明确。