The specific sequence you inquired about, from *
to **
, does not involve any microtasks being performed immediately. However, a microtask is scheduled for later execution during this sequence.
When an async
function is called, it behaves synchronously until encountering the first await
, uncaught exception, or return
statement. At that point, a promise is returned and the synchronous execution resumes from the caller's context. If there was an exception or a return
, a microtask is queued to handle the promise resolution (either rejection or fulfillment).
The parts of the code that are synchronous have been highlighted in yellow:
https://i.sstatic.net/zRDN7.png
In your scenario, when you invoke async1
at the end, its synchronous part runs by logging Async 1
, then calls async2
which logs FROM async 2
synchronously. Upon receiving a promise from async2
, async1
encounters the await
keyword and returns its own promise. Subsequently, synchronous execution proceeds after this call, logging Synchronous
.
Between the segments marked with *
and **
, a microtask is queued to handle the completion of the promise from async2
. Once the current task completes, this microtask is executed, resolving async1
's promise. Following this, async1
continues its operations, performs the log, and implicitly returns. A final microtask is queued to process this last settlement, but since nothing depends on this promise at that stage, no visible outcome occurs.