What gets logged?
Prompt
What gets logged when the following code is executed?
setTimeout(() => console.log(1));
Promise.resolve().then(() => console.log(2));
Promise.resolve().then(() =>
setTimeout(() => console.log(3))
);
new Promise(() => console.log(4));
setTimeout(() => console.log(5));
Solution
Fundamentally, this code is exploring how JavaScript handles different types of asynchronous operations. There are two key mechanisms at play here:
- The task queue (also called the macrotask queue)
- The microtask queue
Let's analyze the code step by step
setTimeout(() => console.log(1));
Promise.resolve().then(() => console.log(2));
Promise.resolve().then(() =>
setTimeout(() => console.log(3))
);
new Promise(() => console.log(4));
setTimeout(() => console.log(5));
First Pass: Synchronous Execution
- Line 1: Schedules a callback that logs 1 to be executed later (adds to the macrotask queue)
- Line 2: Creates a resolved Promise and schedules its .then() callback to log 2 (adds to the microtask queue)
- Line 3: Creates another resolved Promise and schedules its .then() callback (adds to the microtask queue)
- Line 4: Creates a new Promise and immediately executes its constructor function, which logs 4 (this is synchronous!)
- Line 5: Schedules another callback that logs 5 to be executed later (adds to the macrotask queue)
So right away, we see 4 printed to the console.
Second Pass: After Synchronous Code Completes
Once the synchronous code is done, the JavaScript engine:
- Processes all microtasks in the microtask queue
- Then processes one macrotask from the macrotask queue
- Returns to step 1 (check microtasks again)
- Continues this cycle
So after the synchronous code, the microtask queue contains
- A callback to log 2
- A callback that will schedule a setTimeout to log 3
The macrotask queue contains
- A callback to log 1
- A callback to log 5
Processing the Microtask Queue
Now JavaScript processes all microtasks:
- Executes the first microtask: logs 2
- Executes the second microtask: schedules a new setTimeout that logs 3 (adds to the macrotask queue)
Processing the Macrotask Queue
After the microtask queue is empty, JavaScript processes the next macrotask:
- Executes the first task from the queue: logs 1
- Checks the microtask queue (it's empty)
- Executes the next task from the macrotask queue: logs 5
- Checks the microtask queue again (still empty)
- Executes the last task from the macrotask queue: logs 3
So the final order of logs is 4
-> 2
-> 1
-> 5
-> 3
Final Output
4; // Immediate (synchronous) execution
2; // First microtask
1; // First macrotask
5; // Second macrotask
3; // Last macrotask (scheduled during microtask processing)
Here's what makes this interesting: JavaScript's event loop always prioritizes microtasks over macrotasks. This means Promise callbacks get processed before setTimeout callbacks, even if the setTimeout was scheduled first.
Think of it like having a VIP lane (microtasks) and a regular lane (macrotasks). JavaScript always serves everyone in the VIP lane before serving even one person from the regular lane.
This is why understanding the event loop is crucial for predicting how asynchronous code will execute in JavaScript.RetryClaude does not have the ability to run the code it generates yet.Claude can make mistakes. Please double-check responses.