Reputation: 11728
This question is very similar in intent to Difference between microtask and macrotask within an event loop context, but more specific, in that it asks for the explication of a definite example: I think for this reason it shouldn't be considered a duplicate.
What is the state Macrotask queue and Microtask queue during the execution of this code in node.js
console.log("A1");
(async ()=> {
console.log("1")
f = async ()=>{console.log('2')}
await f()
console.log("3")
})()
console.log("A2");
Output:
A1
1
2
A2
3
Output I expected: A1, A2, '1','2','3'
Based on this reasoning: log A1 --> enqueue anonymous function on microtask queue --> log A2 --> execute anaonymous function log 1, enqueue f on the microtask queue --> execute f from microtask queue --> log 2 --> log 3
Where am I going wrong? (additionally how is a top level async func enqueued?)
NOTE: actual command used to run this was npx babel-node myscript.js
Upvotes: 3
Views: 160
Reputation: 1075337
You're seeing this behavior because an async
function runs synchronously up until the first await
, explicit return
, or implicit return
(code execution falling off the end of the function).
I'm going to change the code slightly to give the outer async
function a name so it's easier to talk about:
console.log("A1");
const outer = async () => {
console.log("1")
f = async ()=>{console.log('2')}
await f()
console.log("3")
};
outer();
console.log("A2");
Here's what happens:
console.log("A1")
runs (of course).outer()
is called.outer
runs, so it:
console.log("1")
f
f()
f
runs, so it:
console.log('2')
f
implicitly returns, and so it returns its promise to outer
. That promise is already fulfilled with the value undefined
. (See here in the spec.)outer
awaits f
's promise, so it returns its promise to the caller (which throws it away, but that doesn't matter).outer
awaiting f
's promise queued a microtask to continue outer
because f
's promise is already settled.console.log("A2")
runs.outer
to continue and do console.log("3")
.Upvotes: 1