How the JavaScript Event Loop Works
Understand the JavaScript event loop, call stack, task queue, and microtask queue so async code, promises, and timers make sense.
For publishers, affiliate sites, and product-comparison pages, these skills directly improve page usability, engagement, and conversion flow.
The Simple Mental Model
JavaScript can only execute one stack frame at a time in a given thread. The event loop is the scheduling mechanism that keeps this single-threaded model practical. It watches the call stack, the task queue, and the microtask queue, deciding what should run next once the current synchronous work finishes.
Call Stack, Task Queue, and Microtasks
Call stack
This is where synchronous code runs immediately.
Task queue (often called macrotask queue)
Timer callbacks, many DOM events, and other queued tasks wait here until the call stack is clear.
Microtask queue
Promise callbacks are typically queued here. Microtasks run before the engine moves on to the next task queue item, which is why promise callbacks often run before a setTimeout(..., 0) callback.
Why Output Order Surprises Beginners
Beginners often expect “zero milliseconds” to mean “immediately.” But setTimeout(..., 0) means “queue this task as soon as possible,” not “run it now.” It still must wait until the current synchronous work finishes and after pending microtasks are processed.
Why the Event Loop Matters in Real Projects
- It explains why UI can freeze when heavy synchronous work blocks the stack.
- It explains why promise callbacks appear before timer callbacks.
- It helps you debug race conditions, loading states, and timing-related bugs.
- It improves performance decisions when building filters, widgets, and comparison tools.
Quick comparison table
Use this table as a fast-reference cheat sheet while reading or revisiting the topic later.
| Part | Job | Typical examples | Key rule |
|---|---|---|---|
| Call stack | Runs current code | Function calls, synchronous logic | Only one thing runs at a time |
| Task queue | Holds queued tasks | setTimeout, DOM events | Runs when the stack is empty |
| Microtask queue | Higher-priority queued work | Promise callbacks, MutationObserver | Emptied before the next task queue item |
Practical example
A small example often makes the concept click faster than abstract definitions alone.
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');
// Output:
// A
// D
// C
// BExplore Our Powerful Digital Product Bundles
Browse these high-value bundles for website creators, developers, designers, startups, content creators, and digital product sellers.
If you build landing pages, review sites, affiliate assets, UI mockups, or digital products around JavaScript-powered experiences, these bundles can help you move faster.
Further reading
Continue on SenseCentral
Useful external resources
Key takeaways
- The event loop schedules what runs after current synchronous code finishes.
- The call stack handles current execution; queues hold deferred work.
- Microtasks generally run before task queue callbacks.
- setTimeout(…, 0) does not mean immediate execution.
- Understanding the event loop makes async output order much easier to debug.
FAQs
Is JavaScript multi-threaded?
The language model you usually experience in the browser is single-threaded per execution context, but the environment can coordinate other background work.
Why does Promise.then() often run before setTimeout(…, 0)?
Because promise callbacks are typically processed from the microtask queue before the next task queue callback runs.
What is the event loop really solving?
It lets JavaScript stay responsive while coordinating asynchronous work in a predictable order.
Do I need to master this as a beginner?
You do not need every edge case immediately, but you should understand the core model early.


