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

  1. 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.
  2. 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.

Event Loop Execution Order

The event loop processes tasks in the following order:

  1. Execute all the synchronous code (currently running script).
  2. Execute all microtasks that are queued (e.g., .then(), .catch() of Promises).
  3. Execute a macrotask (e.g., setTimeout, I/O operations).
  4. After the macrotask, it goes back to process microtasks again if any are queued.
  5. Continue the loop.

Key Differences Between Microtasks and Macrotasks

FeatureMicrotasksMacrotasks
Execution TimingExecutes after the current script and before the next macrotask.Executes after all microtasks are completed.
ExamplesPromises (.then, .catch), queueMicrotask()setTimeout(), setInterval(), I/O events
Queue TypeMicrotask queueTask queue
PriorityHigher priority than macrotasks.Lower priority than microtasks.
FrequencyMicrotasks 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:

javascript
console.log('Script Start'); setTimeout(() => { console.log('Macrotask 1'); }, 0); Promise.resolve().then(() => { console.log('Microtask 1'); }).then(() => { console.log('Microtask 2'); }); setTimeout(() => { console.log('Macrotask 2'); }, 0); console.log('Script End');

Expected Output:

sql
Script Start Script End Microtask 1 Microtask 2 Macrotask 1 Macrotask 2

Explanation of Execution Order:

  1. Synchronous code: The script starts, and "Script Start" is printed to the console. Then "Script End" is printed immediately after.

  2. 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.
  3. 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".

Why Does This Happen?

The event loop always checks for microtasks first before processing macrotasks. Here's the step-by-step flow:

  1. The synchronous code executes first.
  2. Then the microtask queue is executed, which handles all promises, queueMicrotask() calls, etc.
  3. Finally, the event loop processes macrotasks (like setTimeout and I/O operations).
  4. 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

Popular posts from this blog

PrimeNG tutorial with examples using frequently used classes

Docker and Kubernetes Tutorials and QnA

oAuth in angular