JavaScript Event Loop & Concurrency Model

JavaScript is single-threaded, meaning it can execute one task at a time.

However, it can handle asynchronous operations using the event loop.

Understanding the event loop is essential for writing efficient and non-blocking code.

Single-Threaded Nature

JavaScript runs on a single thread with one call stack.

Long-running tasks can block the UI if not handled properly.

Call Stack

The call stack is where function execution happens.

Functions are pushed onto the stack and popped after execution.

Web APIs

Browsers provide Web APIs like setTimeout, fetch, and DOM events.

These APIs handle asynchronous operations outside the call stack.

Task Queues

  • Microtask Queue (Promises, queueMicrotask)
  • Macrotask Queue (setTimeout, setInterval, I/O)

Event Loop

The event loop continuously checks if the call stack is empty.

If empty, it pushes tasks from queues into the call stack.

Microtasks are processed before macrotasks.

Microtasks

Microtasks have higher priority than macrotasks.

  • Promise.then()
  • Promise.catch()
  • queueMicrotask()

They are executed immediately after the current task.

Macrotasks

  • setTimeout
  • setInterval
  • setImmediate (Node.js)

They are executed after microtasks are completed.

Execution Order Example

JavaScript
console.log('Start');

setTimeout(() => console.log('Timeout'), 0);

Promise.resolve().then(() => console.log('Promise'));

console.log('End');

Output: Start → End → Promise → Timeout

Blocking the Event Loop

Heavy synchronous tasks block the event loop and delay execution.

This can freeze the UI and degrade user experience.

Optimization Techniques

  • Break long tasks into smaller chunks
  • Use Web Workers for heavy computations
  • Avoid blocking synchronous code
  • Use async/await properly

Web Workers

Web Workers run JavaScript in background threads.

They help offload heavy tasks from the main thread.

Real-World Example

A large loop blocking the thread delays UI updates.

Splitting it into async chunks keeps the UI responsive.

Common Mistakes

  • Blocking the main thread
  • Misunderstanding async execution order
  • Overusing setTimeout for logic control
  • Ignoring microtask priority

Conclusion

The event loop is the backbone of JavaScript's asynchronous behavior.

Understanding it helps developers write efficient, non-blocking code.

Mastering this concept is essential for advanced frontend development.