当关键字后的表达式未计算为 promise 时,`await` 会发生什么?

What should happen with `await` when the expression after the keyword does not evaluate to promise?

我有这样的 ES7 代码。

async function returnsfive() {
  var three = 3;
  var threeP = await three;
  return threeP+2;
}

returnsfive().then(k=>console.log(k), e=>console.error("err", e))

var threeP = await three 行应该发生什么?

代码应该按预期继续,还是失败,因为 three 不是一个承诺?

this repo中提到为"Debatable Syntax & Semantics"。我无法通读官方文档来找到确切的定义,因为它太技术化了。

默认 babel.js 转换记录 5,符合预期;然而,nodent - 一个不同的转换 - 打印 TypeError: three.then is not a function。哪个是正确的,为什么?

根据 current working draft spec,运行时应首先 "cast" 将等待值传递给承诺:

AsyncFunctionAwait ( value )

  1. Let asyncContext be the running execution context.
  2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  3. Let resolveResult be ! Call(promiseCapability.[[Resolve]], undefined, value).
  4. ...

第 2 步和第 3 步的结合大致相当于调用 Promise.resolve(value),它创建一个新的承诺,该承诺用给定的值解决,或者 - 如果该值是一个 thenable - 将遵循那个 thenable。

换句话说:await 3 等同于 await Promise.resolve(3),Babel 正确地实现了规范。

另一方面 deliberately does not support awaiting a non-promise by default。如果您希望首先将所有等待的值包装在承诺中,则可以使用 wrapAwait 选项,但 nodent 文档报告说这可能会影响性能。