MatAtBread / fast-async

603 stars 21 forks source link

fast-async not working when awaiting non-promise #9

Closed karelbilek closed 8 years ago

karelbilek commented 8 years ago

Consider this small code. It is working with Babel implementation.

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

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

See babel repl.

With fast-async, I get

index.js:1362 err TypeError: three.then is not a function

That's not good.

I cannot right now find a formal specification for async/await, so I am not sure which implementation is "correct".

karelbilek commented 8 years ago

Oh, it's a nodent issue that is actually a feature, I think. OK. Closing

https://www.npmjs.com/package/nodent#gotchas-and-es7-compatibility

matAtWork commented 8 years ago

Yes, this seems to be an edge case not covered by the spec. Most references within the spec say "await must be followed by an expression evaluating to a Promise", but the standard generator implementation always wraps the yielded value in a Promise (inside the 'spawn' routine), which means you don't have to 'await' a Promise, since whatever you put after it will get wrapped.

Nodent has an option wrapAwait to always wrap the value, but it does slow things down quite a bit.

If you find a definitive answer, please let me have the reference.

karelbilek commented 8 years ago

http://stackoverflow.com/questions/38884570/what-should-happen-with-await-when-the-expression-after-the-keyword-does-not-e/38884761#38884761

matAtWork commented 8 years ago

Interestingly, I can't find the definition of NewPromiseCapability as used in the spec - it would make sense to assume it requires wrapping, however it's still not clear to me, so I'll leave it as an option for now.

Out of interest, what is your use-case, in the sense of when is awaiting a non-Promise useful to you?

matAtWork commented 8 years ago

..I take that back, it's at http://www.ecma-international.org/ecma-262/6.0/index.html#sec-newpromisecapability. So it looks like wrapping is the standard, and the nodent optimization (not wrapping everything in a Promise) is possible optimization. I'll work out how to handle this case and see if there's a non-breaking solution