- -- operator
- -= operator
- ++ operator
- += operator
- Accessing and setting content
- Array length
- Arrays
- Between braces
- Booleans
- Braces
- Callback function
- Calling the function
- Class
- Closure
- Code block
- Conditions
- Console
- Constructor
- Creating a p element
- Data types
- Destructuring
- Else
- Else if
- Equals operator
- Error Handling
- ES6
- Event loop
- Events
- Extend
- Fetch API
- Filter
- For loop
- Function
- Function name
- Greater than
- Head element
- Hoisting
- If statement
- JSON
- Less than
- Local storage
- Map
- Methods
- Module
- Numbers
- Overriding methods
- Parameters
- Promises
- Reduce
- Regular expressions
- Removing an element
- Replace
- Scope
- Session storage
- Sort
- Splice
- String
- Substring
- Template literals
- Tile
- Type conversion
- While loop
JAVASCRIPT
JavaScript Event Loop: Syntax, Usage, and Examples
The JavaScript event loop is a mechanism that manages asynchronous operations, allowing JavaScript to execute non-blocking code despite being single-threaded. It ensures that tasks like user interactions, network requests, and timers are handled efficiently.
How the JavaScript Event Loop Works
JavaScript uses an event-driven model where asynchronous tasks are queued and executed after synchronous tasks complete. The event loop continuously checks the call stack and task queue, processing queued tasks when the stack is empty.
Understanding the Call Stack
JavaScript executes functions in a last-in, first-out (LIFO) manner using the call stack. When a function is invoked, it is pushed onto the stack and removed once it completes execution.
function greet() {
console.log("Hello!");
}
greet(); // "Hello!"
Here, greet
is added to the stack, executed, and then removed.
Task Queue and the Event Loop
Asynchronous tasks such as setTimeout
, promises, and DOM events are added to a task queue and executed when the stack is clear. The event loop ensures that these tasks are handled in order.
console.log("Start");
setTimeout(() => {
console.log("Inside timeout");
}, 0);
console.log("End");
Despite setTimeout
being set to 0ms
, it runs after "End" because JavaScript first completes all synchronous tasks before checking the queue.
When to Use the JavaScript Event Loop
The event loop plays a key role in managing JavaScript’s execution model. It is useful in several scenarios:
- Handling asynchronous operations such as HTTP requests, file reading, and timers.
- Improving performance by preventing long-running synchronous code from blocking execution.
- Managing animations and real-time user interactions without freezing the UI.
- Handling promises and
async/await
operations efficiently. - Executing code at appropriate times based on task priority.
Examples of the JavaScript Event Loop
Using setTimeout to Delay Execution
A common use case is scheduling a function to execute later using setTimeout
.
console.log("Before delay");
setTimeout(() => {
console.log("This runs after 2 seconds");
}, 2000);
console.log("After delay");
"Before delay" and "After delay" are logged first because setTimeout
places the function in the task queue, and the event loop waits for the stack to clear before executing it.
Processing Multiple Asynchronous Tasks
If multiple tasks are scheduled, they execute in order as the event loop cycles through them.
console.log("First");
setTimeout(() => console.log("Second"), 1000);
setTimeout(() => console.log("Third"), 500);
console.log("Fourth");
The output will be:
First → Fourth → Third → Second
Using Promises in the Event Loop
Promises have higher priority than regular tasks in the event loop and run before setTimeout callbacks.
console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise resolved"));
console.log("End");
The output will be:
Start → End → Promise resolved → Timeout
This happens because promise callbacks are placed in the microtask queue, which is processed before the task queue.
Learn More About the JavaScript Event Loop
Microtasks vs. Macrotasks in the Event Loop
JavaScript has two types of queues:
- Microtasks: Higher-priority tasks that run before macrotasks. Includes promises and
queueMicrotask()
. - Macrotasks: Lower-priority tasks that run after microtasks. Includes
setTimeout
,setInterval
, and DOM events.
console.log("Start");
setTimeout(() => console.log("Macrotask"), 0);
Promise.resolve().then(() => console.log("Microtask"));
console.log("End");
The output will be:
Start → End → Microtask → Macrotask
Using async/await with the Event Loop
async/await
simplifies working with asynchronous code by making it look synchronous while still using the event loop.
async function fetchData() {
console.log("Fetching data...");
await new Promise(resolve => setTimeout(resolve, 2000));
console.log("Data received!");
}
console.log("Before function call");
fetchData();
console.log("After function call");
The output will be:
Before function call → Fetching data... → After function call → Data received!
Even though fetchData
contains an await
, execution continues with the next synchronous statement until the promise resolves.
Event Loop and Single-Threaded JavaScript
JavaScript is single-threaded, meaning it can only run one task at a time. However, the event loop allows non-blocking operations by offloading tasks to the Web API, which handles them asynchronously before placing them in the queue.
console.log("Script start");
setTimeout(() => console.log("Timeout 1"), 0);
setTimeout(() => console.log("Timeout 2"), 0);
console.log("Script end");
The synchronous tasks (logs) execute first, followed by setTimeout
callbacks.
Preventing Event Loop Blocking
Long-running synchronous tasks can freeze the UI, so using techniques like setTimeout
or requestAnimationFrame
can prevent this.
function longTask() {
console.log("Start task");
setTimeout(() => console.log("Task completed"), 0);
}
console.log("Before task");
longTask();
console.log("After task");
Splitting tasks using setTimeout
allows other queued tasks to execute without blocking execution.
The JavaScript event loop enables asynchronous programming by managing task execution order in a non-blocking way. It coordinates the call stack, task queue, and microtask queue, ensuring smooth execution of user interactions, promises, and timers.
Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.