Starvation
Microtask Starvation
Section titled “Microtask Starvation”Introduction
Section titled “Introduction”If microtasks keep queuing new microtasks, the macrotask queue never gets processed. This is called starvation.
The Problem
Section titled “The Problem”// ⚠️ Microtasks keep queuing new microtasksfunction loop() { queueMicrotask(() => { console.log('Microtask'); loop(); // Keeps adding more microtasks });}
loop();
setTimeout(() => { console.log('This may never run!');}, 100);// Macrotasks get starved by infinite microtasksWhy This Matters
Section titled “Why This Matters”In real applications, promise chains could accidentally starve the event loop:
async function processItems(items) { for (const item of items) { // Each await adds a microtask await Promise.resolve().then(() => processItem(item)); }}// This might delay rendering and user interactionsPrevention
Section titled “Prevention”// Yield to the event loop periodicallyasync function processItems(items) { for (const item of items) { processItem(item); // Synchronous processing if (item.index % 100 === 0) { await new Promise(resolve => setTimeout(resolve, 0)); // Yield } }}Summary
Section titled “Summary”- Microtasks run continuously until the queue is empty
- Infinite microtask loops starve macrotasks
- setTimeout, rendering, and I/O can be delayed
- Yield periodically in long microtask chains