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?
According to the current working draft spec, the runtime should "cast" the awaited value to a promise first:
AsyncFunctionAwait ( value )
- Let
asyncContext
be the running execution context.
- Let
promiseCapability
be ! NewPromiseCapability(%Promise%)
.
- Let
resolveResult
be ! Call(promiseCapability.[[Resolve]], undefined, value)
.
- ...
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.