Course outline · 0% complete

0/27 lessons0%

Course overview →

The call stack and the task queue

lesson 4-1 · ~12 min · 9/27

Quiz

Warm-up from lesson 3-1: when you read `rex.describe` and rex has no own `describe`, where does JavaScript look next?

One thread, one stack, one queue

JavaScript runs one thing at a time. The currently-running functions live on the call stack: calling a function pushes it on, returning pops it off.

So what does setTimeout(fn, 0) do? It does not run fn. It registers a timer with the environment (browser or Node) and returns immediately. When the timer expires, the environment places fn in the task queue: a first-in-first-out list of callbacks that are ready to run but have not started.

The event loop is a simple rule that connects them: when the call stack is empty, take the oldest task from the queue and run it. Your currently-running code always finishes first. That is why a 0 ms timeout still runs after every line of your script.

This single-threaded design is why a slow loop freezes a browser tab, why one CPU-hogging request stalls a Node server for every client, and why setTimeout(fn, 0) does not mean "now". Every async bug you will ever debug, and every "what does this print?" interview puzzle, is decided by this machinery.

Code exercise · javascript

Run it. The timeout is 0 ms, yet it prints last: its callback sits in the queue until the whole script has finished and the stack is empty.

call stackmain()task queuetimeout cbevent loop: stack empty? run the next task
setTimeout parks its callback in the task queue. The event loop moves it to the stack only once the stack is empty.

Nothing interrupts the stack

A ready timer cannot force its way in. The event loop only moves a queued task onto the stack when the stack is empty, so a long-running loop blocks every timer, click handler, and network callback until it finishes. That is literally what a "frozen tab" is: the stack never empties, so no queued work ever runs.

Code exercise · javascript

Run it. The timer is ready at 0 ms, but the busy-wait keeps the stack occupied for 50 ms. The callback can only run after `loop finished` prints and the stack empties.

Quiz

Your script starts a `setTimeout(fn, 100)` and then runs a loop that takes 3 whole seconds. When does fn run?

Problem

Predict the output. Write the three letters in the order they print, separated by spaces: ```javascript console.log("a"); setTimeout(() => console.log("b"), 0); console.log("c"); ```