I found that it could be tricky without thinking careful. When exactly does an async function return to the caller?
I will intentionally not making this into a snippet so that the readers can guess what the output is:
What would be printed out:
async function foo() {
console.log("COMING INTO foo");
await new Promise((resolve) => {
setTimeout(resolve, 3000);
});
console.log("Right before return");
return 123;
}
function takeIt(fn) {
console.log("STARTING");
foo();
console.log("Function returned");
}
takeIt(foo);
and why?
Perspective one can be: Well, we all know async function will pause for the setTimeout
and sleep for 3 seconds, and it won't return later on... so
STARTING
COMING INTO foo
Right before return
Function returned
Perspective two can be: Well, foo()
returns 123 (or not return anything and that would mean to return undefined
), and it is a promise... and returning a promise is instantaneous, so it is:
STARTING
Function returned
COMING INTO foo
Right before return
Now if we add one more tweak to the plot:
async function foo() {
await Promise.resolve(678);
console.log("COMING INTO foo");
await new Promise((resolve) => {
setTimeout(resolve, 3000);
});
console.log("Right before return");
return 123;
}
function takeIt(fn) {
console.log("STARTING");
foo();
console.log("Function returned");
}
takeIt(foo);
and there can be some more perspectives... I guessed what is printed for all 3 cases, before I ran the program, and got the correct answers. But I did not know precisely how it works, but I made a guess. Can somebody shred light on precisely how it works, and if needed, I will post my answer a few days later as to how I think it exactly worked.
The question is: when does foo()
return and precisely, how does it work? What is the guiding principle?