Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 496
Karel Bílek Avatar asked Aug 10 '16 22:08

Karel Bílek


1 Answers

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.

like image 138
Mattias Buelens Avatar answered Sep 28 '22 10:09

Mattias Buelens