What should happen with `await` when the expressio

2019-02-12 17:39发布

问题:

I have a ES7 code like this.

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

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

What should happen at the var threeP = await three line?

Should the code continue as expected, or fail, because three is not a promise?

In this repo, it is mentioned as "Debatable Syntax & Semantics". I am not able to read through the official documentation to find the exact definition, since it's too technical.

Default babel.js transformation logs 5 as expected; however, nodent - a different transform - prints TypeError: three.then is not a function. Which is correct and why?

回答1:

According to the current working draft spec, the runtime should "cast" the awaited value to a promise first:

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. ...

Step 2 and 3 combined is roughly equivalent to calling Promise.resolve(value), which creates a new promise that is resolved with the given value or - if the value is a thenable - will follow that thenable.

In other words: await 3 is equivalent to await Promise.resolve(3), and Babel implements the spec correctly.

nodent on the other hand deliberately does not support awaiting a non-promise by default. There's a wrapAwait option available if you want all awaited values to be wrapped in a promise first, but the nodent documentation reports that this may affect performance.