当关键字后面的表达式没有评估为承诺时,`await`会发生什么?

时间:2016-08-10 22:29:56

标签: javascript async-await ecmascript-next

我有这样的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。哪个是正确的,为什么?

1 个答案:

答案 0 :(得分:6)

根据current working draft spec,运行时应首先将等待的值“转换”为承诺:

  

AsyncFunctionAwait( value

     
      
  1. asyncContext成为正在运行的执行上下文。
  2.   
  3. promiseCapability成为! NewPromiseCapability(%Promise%)
  4.   
  5. resolveResult成为! Call(promiseCapability.[[Resolve]], undefined, value)
  6.   
  7. ...
  8.   

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

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

另一方面,

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