🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)

🔧 Programmierung 🕛 kürzlich 7 Min Lesezeit
0

Node.js Event Loop: Visual Guide to Async Programming (2026)

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




Node.js Event Loop: Visual Guide to Async Programming (2026)



The event loop is what makes Node.js fast. Understanding it means writing faster, bug-free async code.






The Big Picture






CODE
┌──────────────────────────────────┐
│ │
│ ┌─────┐ ┌──────────────────┐ │
│ │ Timers│ │ Check │ │
│ │(set │ │ (setImmediate) │ │
│ │Timeout│ │ │ │
│ └──┬──┘ └────────┬─────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────┐ │
│ │ Poll / I/O Callbacks │ │ ← Where most of your code runs!
│ └────────────┬─────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ Close Callbacks │ │
│ └──────────────────────────┘ │
│ │
└──────────────────────────────────┘

Key insight: JavaScript is SINGLE-THREADED.
But I/O (network, file system) happens on SEPARATE threads.
The event loop coordinates everything.









How It Actually Works






CODE
// Each "tick" of the event loop does this:

// Phase 1: Timers (setTimeout, setInterval)
// → Check if any timer has expired. If yes, run its callback.

// Phase 2: Pending callbacks (I/O errors, etc.)
// → Run callbacks deferred from previous I/O operations.

// Phase 3: Poll (the main phase!)
// → Execute I/O callbacks (fs.readFile, http.request, etc.)
// → If no callbacks: wait for new I/O OR run setImmediate callbacks.
// → This is where your app spends most of its time.

// Phase 4: Check (setImmediate callbacks)
// → Run all setImmediate callbacks.

// Phase 5: Close callbacks
// → Run socket.on('close'), etc.

// Then... back to Phase 1! (loop!)









Microtasks vs Macrotasks






CODE
// CRITICAL distinction that causes bugs:

console.log('1. Script start');

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

Promise.resolve()
.then(() => console.log('2. Promise.then (microtask)'))
.then(() => console.log('3. Promise.then #2 (microtask)'));

setImmediate(() => console.log('5. setImmediate (macrotask)'));

process.nextTick(() => console.log('0. process.nextTick (microtask)'));

// Output order:
// 1. Script start
// 0. process.nextTick (microtask) ← HIGHEST priority microtask!
// 2. Promise.then (microtask)
// 3. Promise.then #2 (microtask)
// 4. setTimeout (macrotask)
// 5. setImmediate (macrotask)

// Priority order:
// 1. process.nextTick (same tick, after current operation completes)
// 2. Promises (.then/.catch/.finally) — microtask queue
// 3. Other macrotasks in order: timers → poll → check → close









Common Mistakes & Fixes






Mistake 1: Blocking the Event Loop






CODE
// ❌ Blocking: CPU-heavy operation freezes EVERYTHING
app.get('/compute', (req, res) => {
const result = heavyComputation(data); // Blocks for 5 seconds!
res.json({ result });
});
// During those 5 seconds: NO requests handled, NO timers fire, NO heartbeats!

// ✅ Fix 1: Offload to worker thread
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');

if (isMainThread) {
app.get('/compute', (req, res) => {
const worker = new Worker(__filename, {
workerData: { data: req.body.data }
});
worker.on('message', (result) => {
res.json({ result }); // Main thread stays responsive!
});
});
} else {
const result = heavyComputation(workerData.data);
parentPort.postMessage(result);
}

// ✅ Fix 2: Break into chunks with setImmediate
function processLargeArray(array, callback) {
let index = 0;
const chunkSize = 1000;

function processChunk() {
const end = Math.min(index + chunkSize, array.length);
for (; index < end; index++) {
processItem(array[index]); // Process one item
}
if (index < array.length) {
setImmediate(processChunk); // Yield to event loop, then continue
} else {
callback(); // Done!
}
}
processChunk();
}
// Event loop stays responsive between chunks!

// ✅ Fix 3: Use native async APIs (libuv handles threading)
const crypto = require('crypto');
// crypto.pbkdf2 runs on thread pool — doesn't block event loop!
crypto.pbkdf2(password, salt, iterations, keylen, (err, derivedKey) => {
res.json({ key: derivedKey.toString('hex') });
});









Mistake 2: Unhandled Promise Rejections






CODE
// ❌ Silent failure
async function fetchData() {
throw new Error('Network error'); // Unhandled rejection!
}
fetchData(); // No .catch() → warning in Node.js, crash in future versions!

// ✅ Always handle rejections (at minimum):
fetchData().catch(err => console.error('Fetch failed:', err));

// ✅ Or use global handler as safety net:
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
// In production: log to error tracking service!
});

process.on('uncaughtException', (err) => {
console.error('Uncaught Exception:', err);
// Don't just ignore! Log + graceful shutdown:
cleanupAndExit(1);
});

// ✅ Best: Top-level await with try/catch in main file:
try {
await startServer();
} catch (err) {
console.error('Failed to start:', err);
process.exit(1);
}









Mistake 3: Callback Hell vs Async/Await Anti-Patterns






CODE
// ❌ Old school: Callback hell
fs.readFile('config.json', (err, data) => {
if (err) throw err;
const config = JSON.parse(data);
db.connect(config.dbUrl, (err, client) => {
if (err) throw err;
client.query('SELECT * FROM users', (err, rows) => {
if (err) throw err;
res.json(rows); // Good luck reading this...
});
});
});

// ✅ Modern: Clean async/await
async function handleRequest(req, res) {
try {
const config = JSON.parse(await fs.promises.readFile('config.json'));
const client = await db.connect(config.dbUrl);
const rows = await client.query('SELECT * FROM users');
res.json(rows);
} catch (err) {
console.error(err);
res.status(500).json({ error: 'Internal error' });
}
}

// ⚠️ But avoid THIS anti-pattern:
// ❌ Fire-and-forget (unhandled promise!)
app.get('/data', async (req, res) => {
const data = await fetchData(); // If this throws → unhandled rejection!
res.json(data);
});

// ✅ Wrap route handlers properly:
const asyncHandler = (fn) => (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);

app.get('/data', asyncHandler(async (req, res) => {
const data = await fetchData(); // Errors go to Express error middleware!
res.json(data));
}));









Practical Patterns






Pattern 1: Request Coalescing






CODE
// Multiple requests for same data within window → single fetch
class RequestCache {
constructor(ttl = 1000) {
this.cache = new Map();
this.ttl = ttl;
}

async get(key, fetcher) {
const cached = this.cache.get(key);

// Return cached if fresh
if (cached && Date.now() - cached.timestamp < this.ttl) {
return cached.promise;
}

// If already fetching (in-flight), return same promise
if (cached && !cached.resolved) {
return cached.promise; // Deduplicates concurrent requests!
}

// New request
const promise = fetcher().then(data => {
this.cache.get(key).resolved = true;
return data;
});

this.cache.set(key, { promise, timestamp: Date.now(), resolved: false });
return promise;
}
}

// Usage: 100 simultaneous requests for same user → 1 actual API call
const userCache = new RequestCache(5000); // 5s cache
app.get('/user/:id', async (req, res) => {
const user = await userCache.get(`user:${req.params.id}`, () =>
fetchUserFromAPI(req.params.id)
);
res.json(user);
});









Pattern 2: Rate Limiting with Queue






CODE
// Limit concurrent async operations (e.g., API calls, DB queries)
class ConcurrencyLimiter {
constructor(maxConcurrent = 5) {
this.maxConcurrent = maxConcurrent;
this.running = 0;
this.queue = [];
}

async execute(fn) {
if (this.running >= this.maxConcurrent) {
// Wait for slot to open
await new Promise(resolve => this.queue.push(resolve));
}
this.running++;
try {
return await fn();
} finally {
this.running--;
if (this.queue.length > 0) {
this.queue.shift()(); // Let next waiting task proceed
}
}
}
}

// Usage: Process 1000 files, but only 5 at a time
const limiter = new ConcurrencyLimiter(5);
await Promise.all(
files.map(file => limiter.execute(() => processFile(file)))
);









Pattern 3: Timeout Wrapper






CODE
// Add timeout to ANY async operation
function withTimeout(promise, ms, message = 'Operation timed out') {
return Promise.race([
promise,
new Promise((_, reject) =>
setTimeout(() => reject(new Error(message)), ms)
)
]);
}

// Usage:
const data = await withTimeout(
fetchFromSlowAPI(),
3000,
'API response took too long'
);

// Combined with retry:
async function fetchWithRetry(url, options = {}) {
const { maxRetries = 3, timeout = 5000, delay = 1000 } = options;

for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await withTimeout(fetch(url), timeout);
} catch (err) {
if (attempt === maxRetries) throw err;
console.warn(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
await new Promise(r => setTimeout(r, delay * attempt)); // Exponential backoff
}
}
}









Debugging Async Code






CODE
// Enable async stack traces (Node.js 16+)
// --async-stack-traces flag or via code:
Error.stackTraceLimit = Infinity; // Show full stack traces

// Track active promises (debugging hanging operations):
const activePromises = new Set();

function trackableFetch(url) {
const promise = fetch(url).finally(() => activePromises.delete(promise));
activePromises.add(promise);

// Auto-warn if promise takes too long
setTimeout(() => {
if (activePromises.has(promise)) {
console.warn(`⚠️ Pending promise for ${url} (>10s)`);
}
}, 10000);

return promise;
}

// Async hooks (advanced debugging):
import async_hooks from 'async_hooks';

const hook = async_hooks.createHook({
init(asyncId, type, triggerAsyncId) {
if (type === 'PROMISE') {
// Track every promise creation
}
},
destroy(asyncId) {
// Track cleanup
},
});
hook.enable();

// Practical: Measure async operation duration
function measureTime(label) {
const start = process.hrtime.bigint();
return {
end(result) {
const duration = Number(process.hrtime.bigint() - start) / 1e6;
console.log(`${label}: ${duration.toFixed(2)}ms`);
return result;
},
};
}

// Usage:
const timer = measureTime('DB query');
const rows = await db.query('SELECT * FROM users');
timer.end(rows);









What's the trickiest async bug you've ever debugged?



Follow @armorbreak for more practical developer guides.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
GPT-6 Astra Release Today? OpenAI’s Next Major AI Model Is Almost Here
1 Quelle
Apple accuses OpenAI of destroying evidence as trade-secrets fight intensifies
1 Quelle
Major AI platforms go down in unprecedented simultaneous outage
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Node.js Event Loop: Visual Guide to Async Programming (2026)

Thematisch verwandte Begriffe: Nodejs, Event, Loop, Visual · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...