In async functions in JavaScript, returning the result from an async function (i.e. a Promise object) is the same as returning the fulfilled value from that Promise. In code, assuming innerFn
is async, this:
return await innerFn();
}
is the same as this:
return innerFn();
}
But this goes even further. A "thenable" is just any JS object that has a then()
function. All Promises are thenables. But returning a thenable from an async function, even if it's not a Promise, will run that function automatically for you, and there doesn't seem to be a way to turn off the magic.
So, for example:
const a = {};
a.then = onFulfilled => onFulfilled(123);
return a;
}
await outerFn(); // returns `123`
It's even encouraged to let this magic run (i.e. to skip the await
from outerFn
, in this example), even though it cripples stack traces and arguably obscures what's happening.
Now, consider the following example:
return {
id: 1,
name: 'John Smith',
then: () => 'What an unfortunate name for a function in this object. It would be a shame if everything broke because of it.',
};
}
async function outerFn() {
return innerFn();
}
const result = await outerFn();
console.log(result); // Never happens :(
We don't like magic or surprises here. And we do like complete stack traces. My god.