Event loop - Microtasks/Macrotasks
Miscellaneous: Event loop
How is the event loop defined in the JavaScript engine?
View Answer:
Interview Response: In computer science, the event loop is a programming construct or design pattern that waits for and dispatches events or messages in a program. The event loop concept is quite simple. There is an endless loop where the JavaScript engine waits for tasks, executes them, and then sleeps, waiting for more tasks. The general algorithm of the engine includes simple steps. Where there are tasks execute theme, starting with the oldest task first. Then, sleep until a new task appears, then go to one. That is a formalization of what we see when browsing a page. The JavaScript engine does nothing most of the time, and it only runs if a script/handler/event activates.
Diagram:


How are the tasks from the queue processed or handled?
View Answer:
Interview Response: The event loop handles tasks in the queue in the order they are received. When the browser engine completely processes the script, it handles the mousemove event, followed by the setTimeout handler, and so on.
Diagram:


What is the best method to avoid difficulties caused by CPU-intensive tasks?
View Answer:
Interview Response: We can avoid problems by splitting the big task into pieces or chunks. The goal is to split your tasks into smaller chunks to reduce the load on the engine. We should note that the engine is limited to the number of tasks it can process within a given time.
Code Example:
let i = 0;
let start = Date.now();
function count() {
// do a piece of the heavy job (*)
do {
i++;
} while (i % 1e6 != 0);
if (i == 1e9) {
alert('Done in ' + (Date.now() - start) + 'ms');
} else {
setTimeout(count); // schedule the new call (**)
}
}
count();
What is a Microtask in JavaScript?
View Answer:
Interview Response: Microtasks come solely from our code. Promises usually create them: an execution of .then/catch/finally handler becomes a microtask. Microtasks are used “under the cover” of await, as it is another form of promise handling. There is also a special function `queueMicrotask(func)` that queues func for execution in the microtask queue.
Immediately after every macro task, the engine executes all tasks from the microtask queue before running any other macro tasks or rendering or anything else. All microtasks complete before any other event handling, rendering, or macrotask.
Immediately after every macro task, the engine executes all tasks from the microtask queue before running any other macro tasks or rendering or anything else. All microtasks complete before any other event handling, rendering, or macrotask.
Code Example:
// 3rd: alerts "timeout" - timeout shows last because it is a macrotask.
setTimeout(() => alert("timeout"));
// 2nd: alerts "promise" -
// promise shows second, because .then passes through the microtask queue
Promise.resolve()
.then(() => alert("promise"));
// 1st: alerts "code" –
code shows first because it is a regular synchronous call.
alert("code");
Code Example: Simple Algorithm
- Dequeue and run the oldest task from the macrotask queue (e.g., “script”).
- Execute all microtasks
- While the microtask queue is not empty
- Dequeue and run the oldest microtask.
- Render changes, if any.
- If the macrotask queue is empty, wait till a macrotask appears.
- Go to step 1.