Explain difference between Microtask and macrotask in javascript with examples
In JavaScript, the event loop handles asynchronous code execution. Two important types of tasks handled by the event loop are microtasks and macrotasks. Understanding the difference between these two is crucial for understanding how JavaScript handles concurrency, especially when dealing with setTimeout
, Promise
, and other asynchronous APIs.
Microtask vs Macrotask
Microtasks:
- Microtasks are tasks that are executed after the current script has finished execution but before any other macrotask is executed. These tasks are executed at the end of the current event loop iteration, after the synchronous code has completed but before the event loop continues with macrotasks.
- Promises and
queueMicrotask()
are examples of microtasks. - Microtasks are executed immediately after the current task (script execution) finishes, before any rendering or macrotask execution.
Macrotasks:
- Macrotasks (also called "tasks") are tasks that are scheduled to be executed in the next iteration of the event loop. These tasks can include operations like
setTimeout
,setInterval
, or events such as I/O operations (network, file system). - Macrotasks have a lower priority than microtasks and will only be executed after all microtasks in the current event loop are completed.
- Macrotasks (also called "tasks") are tasks that are scheduled to be executed in the next iteration of the event loop. These tasks can include operations like
Event Loop Execution Order
The event loop processes tasks in the following order:
- Execute all the synchronous code (currently running script).
- Execute all microtasks that are queued (e.g.,
.then()
,.catch()
of Promises). - Execute a macrotask (e.g.,
setTimeout
, I/O operations). - After the macrotask, it goes back to process microtasks again if any are queued.
- Continue the loop.
Key Differences Between Microtasks and Macrotasks
Feature | Microtasks | Macrotasks |
---|---|---|
Execution Timing | Executes after the current script and before the next macrotask. | Executes after all microtasks are completed. |
Examples | Promises (.then , .catch ), queueMicrotask() | setTimeout() , setInterval() , I/O events |
Queue Type | Microtask queue | Task queue |
Priority | Higher priority than macrotasks. | Lower priority than microtasks. |
Frequency | Microtasks are executed more frequently because they're executed before macrotasks. | Macrotasks are executed less frequently, only once per event loop iteration. |
Example to Understand the Difference
Let's look at a practical example to observe the order of execution:
Expected Output:
Explanation of Execution Order:
Synchronous code: The script starts, and "Script Start" is printed to the console. Then "Script End" is printed immediately after.
Microtasks: After the synchronous code execution, the microtasks are handled:
- The promise resolved immediately (
Promise.resolve()
), so its.then()
callback (which prints "Microtask 1") is queued as a microtask. - After that, "Microtask 2" is printed because it’s chained in the
.then()
of the previous microtask.
- The promise resolved immediately (
Macrotasks:
- The
setTimeout()
callbacks are added to the macrotask queue, but they are executed only after all microtasks are completed. - "Macrotask 1" is printed first, followed by "Macrotask 2".
- The
Why Does This Happen?
The event loop always checks for microtasks first before processing macrotasks. Here's the step-by-step flow:
- The synchronous code executes first.
- Then the microtask queue is executed, which handles all promises,
queueMicrotask()
calls, etc. - Finally, the event loop processes macrotasks (like
setTimeout
and I/O operations). - If more microtasks are added during the execution of microtasks, they will be executed before macrotasks, which means microtasks have higher priority.
Summary
- Microtasks (e.g.,
Promise.then()
,queueMicrotask()
) are executed after the current script and before any macrotasks. They have a higher priority. - Macrotasks (e.g.,
setTimeout()
,setInterval()
, and I/O events) are executed after all the microtasks have been handled in the current event loop cycle.
Understanding this order is critical when working with asynchronous code, as it helps avoid unexpected behaviors in scenarios involving multiple async tasks and helps developers optimize performance in JavaScript applications.
Comments
Post a Comment