bongsmoke.cloud
RFC 4:20 · Section 7 · Field Guide

JavaScript Pandamonium.
The event loop has pandas in it.

This is a working model of the HTML event loop. Guess what order the code logs, watch it run one step at a time, then run the same code on your browser’s real event loop and compare. They match. We checked.

The classic

In 2015 the browsers themselves disagreed on this order (Archibald, “Tasks, microtasks, queues and schedules”). They have since been made to agree. Your interviewer may not have.

console.log('script start');

setTimeout(() => {
  console.log('timeout');
}, 0);

Promise.resolve()
  .then(() => console.log('then 1'))
  .then(() => console.log('then 2'));

console.log('script end');

What order does this log?

Tap the lines in the order you think they print.

  1. …
  2. …
  3. …
  4. …
  5. …
The loop

Watch the pandas

step 0/23 · t=0.0ms (0 JD) · frames 0

Commit a guess to start the loop.The pandas are shy until you commit. Order the lines above, then lock it in.

Call stack

0

runs to completion

empty · the loop may proceed

Red pandas

0

microtasks · all of them, now

no red pandas

Giant pandas

0

tasks · one per turn

no tasks ready

Bamboo break

0

rAF, then paint

no rAF booked

painted 0 · next frame 16.7ms

Console

  1. —
Proof

Run it for real

The same code, on your browser’s actual event loop: real setTimeout, real promises, real queueMicrotask, real requestAnimationFrame. No eval. If the pandas are wrong, this is where you find out.

Simulator

  1. after your guess

Your browser

  1. not run yet

Unscheduled · RFC 4:20 §7.4

The trash pandas

They slipped in under the radar. They are not in the task queue, the microtask queue or the bamboo break, and nothing on this page calls them. They brought possums. They are eating the garbage. We aren’t sure why they’re here.

Eaten by trash pandas
0 of 0
Possums playing dead
0

still referenced — will never be eaten

WeakRef.deref() sample
0/0 gone
Pressure applied
0 B / 256 MB

The curb is empty. Put something out. They might come.

Incident log

  1. Nothing has happened. That is also allowed.
  • Every bag is 200 small objects and 256 KB of ArrayBuffer, registered with a real FinalizationRegistry and then dropped on the spot. When a counter goes up, that is your browser calling back. Not us. We have no way to call them.
  • Possums are held by a global array, a forgotten event listener or a detached DOM node: the three leaks everybody ships. They look exactly like garbage. They are not garbage. The FinalizationRegistry has never once called back about them.
  • Pressure is 32 MB a press, allocated a slice per task and dropped, and 256 MB a visit. Then the button retires. The trash pandas are not paid by the megabyte, and neither is your laptop. The curb holds 96 bags.
  • Chrome has a gc() behind a flag. We do not use it. Nobody schedules the trash pandas, including us.
Normative · Field guide

The field guide

RFC 4:20 Section 7 ends at §7.5. The field guide numbers its own clauses, so nobody cites them as the RFC.

FG.1 Panda behavior

The key words MUST, MUST NOT and MAY are to be read as in RFC 2119, and the pandas are to be read as in the spec. None of this is invented.

  • A giant panda MUST eat to completion. Nothing interrupts a task. Not a click, not a frame, not a promise.
  • When the call stack empties, every red panda MUST be served, including red pandas that arrive while red pandas are being served. There is no limit. That is not a bug; it is the spec, and it is why Pandamonium mode exists.
  • The bamboo break MAY happen between giant pandas: every 16.7ms at 60 Hz, 8.3ms at 120 Hz (0.00019 and 0.000093 JD). The legend above measured yours. The simulator assumes 60. rAF callbacks run first, each followed by its own microtask checkpoint, and then the page paints. A rAF booked during the break waits for the next one.
  • await on a settled value costs one tick. Awaiting another async function costs its whole body, then one more tick.
  • setTimeout(fn, 0) means “not sooner than”, never “now”. Timers leave the heap by due time, then by the order they were set.

FG.2 Known deviations

The model has no network, no input events, no idle callbacks, no task priorities and no 4ms clamp on deeply nested timers. Its clock is simulated: every panda eats in zero time unless stated otherwise. Orderings are exact. Timings are a courtesy. The whole page sets no cookies and remembers nothing, including your score.

FG.3 Trash pandas and possums

Trash pandas are specified in RFC 4:20 §7.4 and possums in RFC 4:20 §7.5. On this page:

  • Trash pandas MUST NOT be scheduled, because they cannot be. They are not tasks, not microtasks and not part of the bamboo break. The spec does not say when they come, or that they come.
  • A trash panda MAY eat any object nothing can reach, at any time, in any order, and SHOULD NOT be asked about it. A FinalizationRegistry callback MAY never run. A page that depends on one is a page that depends on raccoons.
  • A possum MUST NOT be eaten while it is referenced. It is not dead. It is playing dead. A global array, a forgotten listener and a detached DOM node are each enough to keep one on the lawn forever.
  • The counters on this page move only when the browser calls back. They are never animated on a timer, and silence is reported as silence.