Search lands in PR-5.1 (Pagefind).

Explanation Intermediate

Chapter 8 Updated

How Node.js actually executes your code

Watch a mixed sync + async program move through the call stack, libuv, and the event loop, step by step.

  • Full 18m
  • Revision 4m
  • Flow 2m

From node app.js to exit — every stage

flowchart TD
    Init["<b>i · Initialization</b><br/>V8 loads source<br/>libuv event loop idle"]
      --> Mem["<b>ii · Memory Creation</b><br/>GEC pushed<br/>a, b, c = undefined<br/>multiplyFn hoisted"]
    Mem --> Exec["<b>iii · Code Execution</b><br/>a = 10786<br/>b = 20987"]
    Exec --> N1["<b>iv · https.get offload</b><br/>→ OS kernel<br/>(callback A registered)"]
    N1 --> N2["<b>v · setTimeout offload</b><br/>→ libuv timer<br/>(callback B, 5000 ms)"]
    N2 --> N3["<b>vi · fs.readFile offload</b><br/>→ libuv thread pool<br/>(callback C)"]
    N3 --> Mul["<b>vii · multiplyFn FEC</b><br/>x * y = 226215682<br/>FEC popped"]
    Mul --> Turn["<b>viii · console.log(c)</b><br/>GEC pops<br/>call stack EMPTY"]
    Turn --> Loop["<b>ix · Event loop active</b><br/>cycles phases + microtasks"]
    Loop --> Poll1["<b>x · Poll — readFile done</b><br/>File Data …"]
    Poll1 --> Poll2["<b>xi · Poll — API response</b><br/>res.secret"]
    Poll2 --> Timer["<b>xii · Timers — 5 s elapsed</b><br/>setTimeout"]
    Timer --> Exit["<b>xiii · Shutdown</b><br/>uv_run returns<br/>exit code 0"]
 
    classDef init fill:#eaf2f8,stroke:#3a6ea5,stroke-width:2px,color:#1a1915;
    classDef sync fill:#f5efe1,stroke:#6a8a4f,stroke-width:2px,color:#1a1915;
    classDef offload fill:#fdecd3,stroke:#c2410c,stroke-width:2px,color:#1a1915;
    classDef loop fill:#ece5f5,stroke:#6b46c1,stroke-width:2px,color:#1a1915;
    classDef done fill:#e7efd9,stroke:#587640,stroke-width:2px,color:#1a1915;
    class Init,Mem init
    class Exec,Mul,Turn sync
    class N1,N2,N3 offload
    class Loop,Poll1,Poll2,Timer loop
    class Exit done
  • Initialization

    V8 loads the source string; libuv event loop is initialized and idle.

  • Memory creation

    GEC pushed; variables set to undefined; multiplyFn fully hoisted with its body.

  • Code execution

    Sync phase begins — a and b receive their values on the call stack.

  • https.get offload

    Network I/O → OS kernel (epoll / kqueue / IOCP). Callback A stored in libuv.

  • setTimeout offload

    Timer registered with libuv; callback B waits for ~5000 ms to elapse.

  • fs.readFile offload

    File I/O assigned to a libuv thread-pool worker; callback C stored.

  • multiplyFn FEC

    Sync function call — FEC pushed, 10786 × 20987 = 226215682, FEC popped.

  • console.log(c)

    Last sync line runs; GEC pops; call stack is EMPTY — the turning point.

  • Event loop active

    libuv starts cycling through Timers → Pending → Idle → Poll → Check → Close, draining microtasks between each.

  • Poll — file read

    Thread-pool worker finishes; callback C runs and prints "File Data …".

  • Poll — API resp.

    OS notifies libuv; callback A runs and prints res.secret.

  • Timers — 5 s

    5 seconds elapsed; callback B fires from timer queue and prints "setTimeout".

  • Shutdown

    No active handles; uv_run returns; Node.js process exits with code 0.

Comments

Comments are disabled in this environment. Set PUBLIC_GISCUS_REPO, PUBLIC_GISCUS_REPO_ID, and PUBLIC_GISCUS_CATEGORY_ID to enable.