Hey friends,
The JavaScript event loop runs your code one job at a time: it finishes everything on the call stack, then runs every queued microtask (like promise callbacks), then takes the next task (like a setTimeout callback), and repeats. MDN's execution model page describes the same split: microtasks have higher priority, and the microtask queue is drained before the next task is pulled.
The Salesforce JavaScript Developer exam names this directly. Its Asynchronous Programming section (13%) has an objective on using the event loop to determine loop outcomes. In practice that means: read some code, predict what prints in what order.
What are the parts of the event loop?
| Part | What it holds | Examples |
|---|---|---|
| Call stack | The functions running right now | Your synchronous code |
| Web APIs (browser) or libuv (Node.js) | Work happening outside the JavaScript thread | Timers, network requests, file reads |
| Task queue (macrotasks) | Callbacks ready to run, one per loop turn | setTimeout, setInterval, DOM events, I/O callbacks |
| Microtask queue | Callbacks that run as soon as the stack empties, all of them | Promise then/catch/finally, await continuations, queueMicrotask |
JavaScript itself is single-threaded. Timers and network calls happen elsewhere, and when they finish, their callbacks wait in a queue until the stack is empty.
Why does a promise run before setTimeout?
Because promise callbacks are microtasks and setTimeout callbacks are tasks. After the current script finishes, the loop drains all microtasks first. A setTimeout(fn, 0) still waits for that.
Walk it through: A and E are synchronous. C and D are microtasks, queued in that order. B is a task, so it runs last, even with a 0 ms delay.
The MDN microtask guide adds one more detail: if a microtask queues another microtask, that one also runs before the loop moves on. So a microtask that keeps queuing microtasks can starve rendering and timers.
Cert Lab by Nick Frates
Let the JavaScript Developer Cert Lab test you to success
Output-order and async scenario questions like these for every exam section, with an explanation for every option.
Start the JavaScript Developer Cert Lab for $9.99 →Not ready to buy? Try a free lesson and see how fast you learn.
How does await fit into the event loop?
Code after await runs as a microtask once the awaited promise settles. Everything before the first await in an async function runs synchronously.
More on that in my async/await guide.
How is the Node.js event loop different?
Node.js has the same idea with more structure. According to the Node.js event loop guide, each turn moves through phases in order:
- timers: setTimeout and setInterval callbacks
- pending callbacks: some deferred system I/O callbacks
- idle, prepare: internal use
- poll: new I/O events and their callbacks
- check: setImmediate callbacks
- close callbacks: for example a socket's close event
process.nextTick isn't part of the loop's phases. Its queue is processed after the current operation completes, regardless of the current phase, before the loop continues. That's why the docs warn that recursive nextTick calls can starve I/O.
Run from the main module, the order of timeout and immediate isn't guaranteed. The Node.js guide says it depends on process performance. Inside an I/O callback, setImmediate always runs first.
What does blocking the event loop mean?
A long synchronous task, like a huge loop or JSON.parse on a giant string, keeps the stack busy. No clicks are handled, nothing renders, no timers fire. In a Lightning web component that feels like a frozen page. Break big work into chunks, or move it off the main thread with a web worker.
What event loop mistakes should you avoid?
- Treating setTimeout(fn, 0) as instant. It runs after all microtasks and at least after the current task.
- Thinking promises make code run in parallel. They schedule callbacks; your JavaScript still runs on one thread.
- Assuming timer delays are exact. The delay is a minimum. A busy stack delays it further.
- Starving the loop with endless microtasks or nextTick calls.
For the promise side of this, read JavaScript promises explained.
Here's why I care about practice questions so much. I earned 17 Salesforce certifications, and Focus on Force was a big part of that. My early approach was study guide first, tests later. Flipping it, taking practice tests fast and often, cut my study time way down. Cert Lab is my version of that: fast testing with explanations that link to current docs.
FAQ
What is the event loop in JavaScript, in simple terms?
The mechanism that runs queued callbacks one at a time whenever the call stack is empty, with microtasks first and then the next task.
What's the difference between a microtask and a macrotask?
Microtasks (promise callbacks, queueMicrotask) all run as soon as the stack empties. Macrotasks, or tasks (setTimeout, events), run one per loop turn after the microtasks.
Is JavaScript multithreaded?
Your JavaScript runs on one thread per realm. The browser or Node.js does timers and I/O elsewhere and queues the callbacks. Web workers add separate threads with their own event loops.
Is the event loop on the Salesforce JavaScript Developer exam?
Yes, in the Asynchronous Programming section. See my JavaScript Developer study guide.
Where should you go next?
- JavaScript promises for then, catch and chaining.
- JavaScript closures, which pair with the var-in-a-loop timer puzzle.
- JavaScript Developer practice questions to test yourself.
Nick Frates, a senior Salesforce developer with 17 certifications, built the JavaScript Developer Cert Lab at nickfrates.com: rapid-fire practice questions for every exam section, each answer explained.
Cert Lab by Nick Frates
Let the JavaScript Developer Cert Lab test you to success
Lessons, flashcards, a quiz for each of the seven exam sections and full practice exams, every answer explained.
Start the JavaScript Developer Cert Lab for $9.99 →Not ready to buy? Try a free lesson and see how fast you learn.
Hope this helps!
Best,
Nick


