JavaScript concurrency tool • 2026 standards
| Step | Task | Type | Time | Status |
|---|
| Frame | Call Stack | Microtasks | Macrotasks | Render |
|---|
The event loop is a programming construct that waits for and dispatches events or messages in a program. It continuously monitors the call stack and callback queue, executing callbacks when the call stack is empty. This mechanism enables JavaScript's single-threaded, non-blocking nature by handling asynchronous operations without blocking the main execution thread.
The event loop follows this algorithm:
Where:
JavaScript execution follows this priority order:
What is the correct execution order of tasks in the JavaScript event loop?
The answer is A) Synchronous → Microtasks → Macrotasks. JavaScript executes synchronous code first, then processes all microtasks (Promise callbacks, queueMicrotask), then executes one macrotask (setTimeout, setInterval), repeating this cycle continuously.
This is fundamental to understanding JavaScript's execution model. Synchronous code runs immediately, microtasks run after the current execution context finishes but before the next macrotask, and macrotasks run one at a time. This order ensures predictable execution and prevents microtasks from starving macrotasks.
Synchronous Code: Code that executes immediately
Microtasks: High-priority async callbacks
Macrotasks: Lower-priority async operations
• Synchronous code runs first
• All microtasks execute before next macrotask
• Event loop processes one macrotask at a time
• Remember: Sync → Micro → Macro
• Microtasks can starve macrotasks if too many
• Use setTimeout(0) to defer to next macrotask
• Confusing microtask and macrotask priorities
• Not understanding execution order
• Assuming setTimeout(0) executes immediately
Explain why Promise callbacks execute before setTimeout callbacks when both are scheduled at the same time.
Promise callbacks are microtasks, while setTimeout creates macrotasks. The event loop executes all microtasks before processing the next macrotask. Therefore, when both are scheduled simultaneously, the Promise callback (microtask) will execute before the setTimeout callback (macrotask).
This demonstrates the priority system in JavaScript's event loop. Microtasks have higher priority than macrotasks, ensuring that Promise-based operations (which are often chained) complete before other async operations. This prevents race conditions and ensures predictable execution order.
Microtasks: High-priority async callbacks (Promise, queueMicrotask)
Macrotasks: Regular async operations (setTimeout, setInterval)
Priority Queue: Tasks processed in order of priority
• Microtasks execute before next macrotask
• All microtasks complete before moving to next macrotask
• Event loop processes one macrotask at a time
• Promise callbacks are microtasks
• setTimeout/setInterval are macrotasks
• queueMicrotask() forces microtask execution
• Assuming same execution time means same priority
• Not understanding microtask vs macrotask differences
• Expecting synchronous-like behavior from async operations
A developer creates a recursive Promise chain that keeps resolving new Promises. What happens to the event loop, and how could this cause problems? How can this be prevented?
Problem: The recursive Promise chain creates an infinite series of microtasks. Since all microtasks execute before the next macrotask, the event loop gets stuck processing microtasks, preventing macrotasks (like UI rendering, setTimeout) from running. This causes UI freezing and prevents other async operations.
Prevention: Break the infinite chain by introducing a macrotask (setTimeout) periodically, or use iterative approaches instead of recursive promises.
This scenario demonstrates microtask starvation, where continuous microtask creation prevents the event loop from processing macrotasks. It highlights why the event loop processes all microtasks before moving to the next macrotask - while this ensures Promise chains complete efficiently, it can lead to blocking behavior if not managed properly.
Starvation: When one task type prevents others from executing
Microtask Starvation: Microtasks preventing macrotask execution
Recursive Chain: Self-referencing async operations
• Event loop processes all microtasks before next macrotask
• Infinite microtasks can starve macrotasks
• UI rendering occurs after macrotask
• Use setTimeout(0) to break long microtask chains
• Implement iteration instead of recursion for promises
• Monitor for infinite async loops
• Creating infinite recursive promise chains
• Not understanding microtask execution model
• Assuming microtasks are non-blocking
A web application updates the UI inside a Promise callback and also schedules a UI update with setTimeout. Which update happens first, and why? How does this affect user experience?
Order: The Promise callback (microtask) executes first, followed by the setTimeout callback (macrotask). This is because microtasks execute before the next macrotask in the event loop cycle.
User Experience: The Promise-based UI update occurs immediately after the current execution context, while the setTimeout update occurs later. This allows developers to prioritize critical UI updates (via Promises) over less urgent ones (via setTimeout).
This demonstrates practical implications of task priority in UI development. Developers can leverage microtask priority for immediate UI feedback (like showing loading states) while deferring less critical updates (like analytics tracking) to macrotasks. Understanding this helps create more responsive user interfaces.
UI Update: Changes to the Document Object Model
Responsiveness: How quickly UI responds to user actions
Task Priority: Order in which tasks execute
• Microtasks execute before next macrotask
• UI rendering happens after macrotask
• Priority affects perceived performance
• Use Promise for immediate UI feedback
• Use setTimeout for deferred updates
• Batch DOM updates for performance
• Not understanding update timing
• Updating DOM too frequently
• Assuming all async operations have same priority
What is the relationship between queueMicrotask and Promise.then in the event loop?
The answer is B) Both are microtasks with same priority. Both queueMicrotask and Promise.then callbacks are microtasks and execute in the same phase of the event loop, following FIFO order within the microtask queue.
While both are microtasks, they share the same queue and execution phase. The order of execution depends on when they were scheduled - the first scheduled microtask executes first, regardless of whether it came from queueMicrotask or Promise.then.
queueMicrotask: Function to schedule microtask
Promise.then: Method that creates microtask
FIFO: First In, First Out execution order
• Both are microtasks
• Same execution priority
• FIFO within microtask queue
• Both execute before next macrotask
• Order depends on scheduling time
• Use either for microtask scheduling
• Assuming different priorities for microtasks
• Not understanding shared microtask queue
• Confusing with macrotask differences
Continuous cycle monitoring call stack and callback queue.
Synchronous → Microtasks → Macrotasks
Ensures non-blocking JavaScript execution.
Choose micro/macro tasks appropriately for performance.
Q: Why doesn't setTimeout(0) execute immediately?
A: setTimeout(0) creates a macrotask that goes to the callback queue. It executes after current sync code and all microtasks complete, but before the next sync code block.
Q: Microtasks vs Macrotasks?
A: Microtasks (Promise, queueMicrotask) execute before next macrotask. Macrotasks (setTimeout, setInterval) execute one at a time between microtask batches.