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.