JS EVENT LOOP

JS Await Mechanics: What await Actually Waits For

💡
The Core Rule: await does not wait for "all background work in the function to finish". It evaluates one specific expression, wraps that single result in Promise.resolve(expr), and suspends the current async function on the microtask queue until that single Promise settles.

📄 Async Code Inspection

forEach_trap
Expression Under Await
Evaluated: users.forEach(...) → undefined
Runtime Wrap: Promise.resolve(undefined) (Settles at Tick 2)

âš™ī¸ Runtime State & Queues

Step 1 of 5
Call Stack (Synchronous) 1 frame
Microtask Queue 0 tasks
Macrotask / Timer Queue 0 tasks
Floating / Unawaited Promises 0 floating
No unawaited background operations.
Console Output
Tick 0

🔍 Architectural Verdict & Fix Comparison

PREMATURE EXIT
âš ī¸ Premature Completion Bug
users.forEach() returns undefined synchronously. Therefore, await only pauses until Promise.resolve(undefined) settles on the very next microtask tick. The fetchUser async callbacks are left floating in the background unawaited, and "Done" logs before user data arrives.

Side-by-Side Solution Pattern

❌ Buggy Pattern (Awaiting non-promise / void return)
await users.forEach(async (u) => {
  await fetchUser(u);
});
console.log('Done'); // Logs too early!
✅ Corrected Pattern (Promise.all or for...of)
// Parallel execution:
await Promise.all(users.map(async (u) => {
  await fetchUser(u);
}));
console.log('Done'); // Guaranteed after all settle!
Audited Execution Log & Trace
Download full JSON execution telemetry and markdown breakdown for team code reviews.
Enjoy this tool? Build your own with Super