babel / kneden

Transpile ES2017 async/await to vanilla ES6 Promise chains: a Babel plugin
ISC License
514 stars 41 forks source link

Why does awaiting resolve a new Promise? #25

Closed AprilArcus closed 8 years ago

AprilArcus commented 8 years ago

Currently,

async function test() {
  await db.destroy();
}

transpiles to

function test() {
  return Promise.resolve().then(function () {
    return db.destroy();
  }).then(function () {});
}

instead of

function test() {
  return db.destroy().then(function () {});
}

Why is this? We know the expression to the right of await must be a Promise, so this seems overcautious.

ljharb commented 8 years ago

You might know that, but the program can't know that - it might be a Promise, or a generic thenable, or a normal value. By spec, anything awaited must be coerced into a native Promise, whether it is one or not.

AprilArcus commented 8 years ago

Thanks for the clarification! I was not aware that plain values were legal in that position.

What about

function test() {
  return Promise.resolve(db.destroy).then(function () {});
}

?

ljharb commented 8 years ago

@AprilArcus that would make a promise for the db.destroy function - and if you did Promise.resolve(db.destroy()) then that would a) run synchronously instead of correctly on the next tick, and b) if that threw an exception, it would not create a rejected promise.

AprilArcus commented 8 years ago

Thanks, I think I understand correctly now :)