Event Loop in JavaScript
The event loop is a fundamental concept in JavaScript that allows for asynchronous programming. It is responsible for executing code, collecting and processing events, and executing queued sub-tasks.
How the Event Loop Works
JavaScript is single-threaded, meaning it can execute one piece of code at a time. The event loop allows JavaScript to perform non-blocking operations by offloading operations to the system kernel whenever possible.
Components of the Event Loop
- Call Stack: The call stack is where the JavaScript engine keeps track of function calls.
- Web APIs: These are provided by the browser (or Node.js) and include things like
setTimeout,DOM events, andHTTP requests. - Callback Queue: This is where functions are queued up to be executed after the call stack is clear.
- Event Loop: The event loop continuously checks the call stack to see if it's empty. If it is, it takes the first event from the callback queue and pushes it to the call stack.
Example of the Event Loop
Here's a simple example to illustrate how the event loop works:
console.log("Start");
setTimeout(() => {
console.log("Timeout");
}, 0);
console.log("End");
Output:
Start
End
Timeout
Explanation
console.log("Start")is executed and "Start" is printed.setTimeoutis called, and the callback is sent to the Web API. The main thread continues.console.log("End")is executed and "End" is printed.- The event loop checks the call stack and finds it empty. It then pushes the
setTimeoutcallback to the call stack. - The
setTimeoutcallback is executed and "Timeout" is printed.
Event Loop in Action
Here's a more complex example to demonstrate the event loop in action:
console.log("Start");
setTimeout(() => {
console.log("Timeout 1");
}, 1000);
setTimeout(() => {
console.log("Timeout 2");
}, 0);
Promise.resolve().then(() => {
console.log("Promise");
});
console.log("End");
Output:
Start
End
Promise
Timeout 2
Timeout 1
Explanation
console.log("Start")is executed and "Start" is printed.setTimeoutwith 1000ms delay is called and the callback is sent to the Web API.setTimeoutwith 0ms delay is called and the callback is sent to the Web API.Promise.resolve().thenis called and the callback is sent to the microtask queue.console.log("End")is executed and "End" is printed.- The event loop checks the call stack and finds it empty. It then processes the microtask queue first, executing the
Promisecallback and printing "Promise". - The event loop then processes the callback queue, executing the
setTimeoutwith 0ms delay and printing "Timeout 2". - Finally, the
setTimeoutwith 1000ms delay is executed and "Timeout 1" is printed.
Microtasks vs Macrotasks
Microtasks (e.g., Promises) have higher priority than macrotasks (e.g., setTimeout). The event loop processes all microtasks before moving on to the next macrotask.
Example of Microtasks and Macrotasks
console.log("Start");
setTimeout(() => {
console.log("Timeout");
}, 0);
Promise.resolve().then(() => {
console.log("Promise 1");
}).then(() => {
console.log("Promise 2");
});
console.log("End");
Output:
Start
End
Promise 1
Promise 2
Timeout
Explanation
console.log("Start")is executed and "Start" is printed.setTimeoutis called and the callback is sent to the Web API.Promise.resolve().thenis called and the callback is sent to the microtask queue.console.log("End")is executed and "End" is printed.- The event loop processes the microtask queue, executing the
Promisecallbacks and printing "Promise 1" and "Promise 2". - The event loop then processes the callback queue, executing the
setTimeoutcallback and printing "Timeout".