Hacker DirectoryHacker Directory

WEB / WEB-10.03

JavaScript execution and the event loop

Separate synchronous code,Promise executor,microtasks and later tasks in a bounded ordering fixture.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Task + microtasks

  1. Before synchronous start

    The fixture is ready;callback logs and queue outcomes have not yet been produced.

    Synchronous stack
    Stack:empty
    Microtask checkpoint
    Microtasks:[]
    Later task
    Timer:not scheduled
    Presentation boundary
    Paint:not measured
  2. Executor runs now

    Script start and the Promise executor run synchronously;the then callback has not run.

    Synchronous stack
    Log:start,executor
    Microtask checkpoint
    Reaction queued
    Later task
    Timer:not scheduled
    Presentation boundary
    Paint:not measured
  3. Synchronous prefix ends

    queueMicrotask and timer are scheduled;script:end is logged before current code finishes.

    Synchronous stack
    Log:start,executor,end;stackempty
    Microtask checkpoint
    Microtasks:promise,microtask
    Later task
    Timer:requested0
    Presentation boundary
    Paint:not measured
  4. Promise reaction

    The checkpoint processes the queued Promise reaction first;the timer does not interrupt the prefix.

    Synchronous stack
    Prefix complete
    Microtask checkpoint
    Log:+promise;queue:microtask
    Later task
    Timer:not processed
    Presentation boundary
    Paint:not measured
  5. Microtask adds one job

    The selected microtask adds one nested job;the checkpoint continues until the queue empties.

    Synchronous stack
    Prefix complete
    Microtask checkpoint
    Log:+microtask;queue:nested
    Later task
    Timer:not processed
    Presentation boundary
    Paint:not measured
  6. Bounded checkpoint drains

    The nested callback runs;the microtask queue is empty without establishing pixels.

    Synchronous stack
    Stack:empty
    Microtask checkpoint
    Log:+nested;queue:[]
    Later task
    Timer:pendingselection
    Presentation boundary
    Paint:not measured
  7. Later timer callback

    The timer runs in a later task;exact elapsed time and its order relative to rAF are not fixed here.

    Synchronous stack
    Stack returns empty
    Microtask checkpoint
    Checkpoint drained
    Later task
    Log:+timer
    Presentation boundary
    Paint:not measured

Executor vs then

  1. Before Promise creation

    The ordinary local script has started;executor and reaction results are not yet available.

    Synchronous stack
    Log:start
    Microtask checkpoint
    Reaction:absent
    Later task
    Timer:none
    Presentation boundary
    Paint:not measured
  2. Executor synchronous

    The Promise constructor calls its executor now;fulfilled state is not callback execution.

    Synchronous stack
    Log:start,executor
    Microtask checkpoint
    Promise:fulfilled;reactionpending
    Later task
    Timer:none
    Presentation boundary
    Paint:not measured
  3. Caller continues

    The constructor returns and the caller logs end;the then reaction does not interrupt the prefix.

    Synchronous stack
    Log:start,executor,end
    Microtask checkpoint
    Reaction:queued
    Later task
    Timer:none
    Presentation boundary
    Paint:not measured
  4. Reaction later

    The checkpoint runs the reaction;executor and reaction have different completion boundaries.

    Synchronous stack
    Stack:empty
    Microtask checkpoint
    Log:+reaction;queueempty
    Later task
    Timer:none
    Presentation boundary
    Paint:not measured

Await continuation

  1. Caller starts

    The caller is ready to invoke an async function;no independent thread is created.

    Synchronous stack
    Caller active
    Microtask checkpoint
    Microtasks:[]
    Later task
    Await:absent
    Presentation boundary
    Paint:not measured
  2. Before await logs

    The async function runs synchronously up to await and records before-await.

    Synchronous stack
    Log:before-await
    Microtask checkpoint
    Continuation:pending
    Later task
    LocalPromise:fulfilled
    Presentation boundary
    Paint:not measured
  3. Caller keeps running

    While the await continuation is deferred,the caller logs after-call before the function resumes.

    Synchronous stack
    Log:before-await,after-call
    Microtask checkpoint
    Continuation:queued
    Later task
    No network operation
    Presentation boundary
    Paint:not measured
  4. Continuation resumes

    The appropriate reaction work records after-await;ordering does not establish CPU parallelism.

    Synchronous stack
    Prefix complete
    Microtask checkpoint
    Log:+after-await
    Later task
    LocalPromise consumed
    Presentation boundary
    Paint:not measured
  5. Boundary retained

    The local continuation is complete;neither a server transaction nor frame receipt follows from this result.

    Synchronous stack
    Stack:empty
    Microtask checkpoint
    Bounded fixture complete
    Later task
    Network:not executed
    Presentation boundary
    Pixels:not captured

ACTORS · STATE · DATA FLOW

Engine,host and browser are distinct

A JavaScript engine parses and evaluates ECMAScript code and may use implementation techniques such as bytecode or JIT. DOM,fetch and timers are web APIs supplied by the browser host. Language semantics can be explained without assuming a particular optimization. JavaScript executing does not establish completion of a network request or creation of the DOM.

Distinguish language objects such as Array and Promise from document and Window.setTimeout. The same language can run with different host APIs in another runtime. Node timer observations are not browser-scheduler evidence here. A small ordering fixture will use actual Chrome,while the pure scene models selected semantic dependencies.

Execution context and call stack

An execution context is the ECMAScript specification’s model for tracking evaluation progress. Function,Realm and environment relationships belong to it; it need not exist as a context object script can inspect. The running context is the top of the context stack. Nested calls transfer control through contexts,but exceptions and async suspension mean every transition is not identical to a simple drawing.

When A calls B,A’s next synchronous line waits for B to return. The lesson uses a call stack to explain that dependency. Its A:start,B,A:end callTrace is an observation,not a capture of engine-internal stack memory. An empty stack also leaves possible pending callbacks,microtasks and host work.

An event loop schedules callback work

The HTML event loop coordinates scripts,user interaction,networking and rendering. One loop can have several task queues with scheduler choices between task sources. A single global FIFO for every network,click and timer callback is therefore misleading. The microtask queue is also distinct from an ordinary task queue.

The ordinary fixture schedules a timer and two microtask sources during one synchronous start. Delay0 asks for a callback that can become runnable later; it does not interrupt current code. This small fixture cannot establish general network/user-event ordering. The scene retains dependencies between the selected jobs without generating milliseconds or FPS results.

Promise executor is synchronous;reaction is a microtask

new Promise(executor) invokes its executor synchronously during creation. resolve may fulfill the Promise,but a then reaction does not interrupt current synchronous statements;it runs as microtask work at an appropriate checkpoint. Treating everything inside a Promise as async confuses executor and reaction.

The fixture prefix is script:start,executor,script:end,followed by the promise reaction. queueMicrotask retains queue order and a checkpoint continues until the queue is empty. The selected callback adds one nested microtask that runs within the same checkpoint. The model stays bounded and supplies no infinite enqueue or browser-locking code.

Await suspends control rather than creating a thread

An async function can run synchronously until its await point. Continuation proceeds through later reaction work even for a fulfilled Promise,while the caller can continue its synchronous work. Await creates no independent CPU thread. Parallel work in another agent or worker needs its own mechanism and communication boundary.

The selected await fixture orders before-await,after-call,after-await around local Promise.resolve("Atlas"). It performs no fetch or server commit. The observation explains continuation timing rather than transaction atomicity or approval for a resource action. A learner can identify which function’s continuation was deferred instead of assuming every async line runs in parallel.

A DOM update is not a frame receipt

A callback can change DOM state,and a rendering opportunity can turn that state into a new view. The current HTML processing model schedules window rendering work through the rendering task source. Do not assume every task forces a paint or every callback is followed by a fixed refresh. Hidden documents and unnecessary rendering also affect updates.

requestAnimationFrame provides a callback before repaint;it is one-shot and generally pauses for hidden/background contexts. This lesson makes no universal ordering claim between a timer and rAF. The artifact deliberately records paintCaptured=false: log order and current DOM text do not measure pixel presentation.

2. Red · Trust & Impact

Read every scenario without motion

Executor/reaction

  1. The executor appeared in the synchronous prefix

    The Promise constructor runs its executor synchronously after script:start and resolves. expectedLog places executor before script:end. Resolution does not imply simultaneous execution of its reaction callback.

    Callback observations
    script:start / executor / script:end
    Continuation gate
    Scheduling pending
    Application completion
    Outcome unknown
  2. The reaction ran after current work finished

    The promise callback runs at the checkpoint after the synchronous prefix, followed by microtask and nested. Work readiness and callback execution are different states. Local scheduling is not network receipt.

    Callback observations
    script:start / executor / script:end
    Continuation gate
    Reaction after script:end / checkpoint order
    Application completion
    Outcome unknown
  3. The work represented by fulfillment remained explicit

    Promise fulfillment describes only its represented work. Data received, body consumed, validation, DOM updates and server commit may have other completion boundaries. This ordinary callback fixture does not measure application persistence.

    Callback observations
    script:start / executor / script:end
    Continuation gate
    Reaction after script:end / checkpoint order
    Application completion
    Callback known / application commit unmeasured
  4. A nested microtask joined the bounded checkpoint

    The microtask callback adds a nested microtask. expectedLog orders promise, microtask, nested and then timer. This finite example does not define all ordering among other task sources or responsiveness timing.

    Callback observations
    promise→microtask→nested→timer
    Continuation gate
    Reaction after script:end / checkpoint order
    Application completion
    Callback known / application commit unmeasured
  5. Timer scheduling was not an execution deadline

    timerDelayArgument is 0 while elapsedMillisecondsExpected remains null. The timer cannot interrupt synchronous work and has no exact-zero-ms guarantee. Callback order and timer latency are different evidence.

    Callback observations
    promise→microtask→nested→timer
    Continuation gate
    Delay argument0 / exact latency not measured
    Application completion
    Callback known / application commit unmeasured
  6. Control was tied to the correct completion invariant

    UI should not derive business success from a done-like log label alone. If the work contract requires validation or commit, those stages must be awaited separately. Network and paint are false here, leaving broader action outcomes UNKNOWN.

    Callback observations
    promise→microtask→nested→timer
    Continuation gate
    Delay argument0 / exact latency not measured
    Application completion
    Define completion contract / do not infer business success

Await boundary

  1. The async function selected a separate continuation

    expectedAwaitTrace is before-await, after-call, after-await. Await does not suspend the caller’s entire execution; the caller can progress while the continuation is deferred. Async does not automatically move CPU work to another thread.

    Callback observations
    before-await / after-call / after-await
    Continuation gate
    Scheduling pending
    Application completion
    Outcome unknown
  2. The deferred continuation was interpreted as a dependency

    after-call does not establish completion of the async work. Product state must explicitly wait for the continuation or outcome on which it depends. Caller progress and successful awaited work are different predicates.

    Callback observations
    before-await / after-call / after-await
    Continuation gate
    Caller progressed / awaited outcome separate
    Application completion
    Outcome unknown
  3. The async keyword did not guarantee responsiveness

    Long synchronous CPU work can delay main-thread work. An async function alone creates no parallelism. Bounded work or appropriate worker design is a separate control; this fixture measures no stall time or device performance.

    Callback observations
    before-await / after-call / after-await
    Continuation gate
    Caller progressed / awaited outcome separate
    Application completion
    Async ≠ automatic CPU parallelism
  4. The call trace retained its specification-alias scope

    expectedCallTrace is A:start, B, A:end. Execution-context diagrams are specification models, not engine-memory captures or native context objects accessible to script. Error stacks may have different representations.

    Callback observations
    A:start→B→A:end / spec aliases
    Continuation gate
    Caller progressed / awaited outcome separate
    Application completion
    Async ≠ automatic CPU parallelism
  5. Lifecycle and cancellation remained separate predicates

    A pending callback is not assumed to run in the same Document throughout its lifetime. Navigation and cancellation are separate predicates. The selected await trace does not simulate every dispatch edge case or document lifetime.

    Callback observations
    A:start→B→A:end / spec aliases
    Continuation gate
    Continuation order known / lifecycle separate
    Application completion
    Async ≠ automatic CPU parallelism
  6. Await scope was not confused with business outcomes

    The story explains continuation order and caller progress without evidence of server mutation, persisted state or UI pixels. Correct async interpretation provides a sound mental model without claiming unperformed runtime work.

    Callback observations
    A:start→B→A:end / spec aliases
    Continuation gate
    Continuation order known / lifecycle separate
    Application completion
    Continuation known / broader outcomes unmeasured

ASSUMPTION · BOUNDARY · CONTROL

Do not confuse ordering with timing

For an authorized review,log order verifies a small dependency,while a0ms timer label does not verify execution at exactly0ms. Network panels,console output and DOM snapshots also have different observation owners. A callback invocation alone does not prove a whole response body was consumed or persistent action committed.

Before running the ordinary branch,predict its synchronous prefix and microtask order. Explain why a timer cannot interrupt that prefix and where the one nested microtask appears in the bounded checkpoint. This is a normal scheduling exercise rather than a way to trigger an attack race. Do not generalize ordering for other task sources from these logs.

A context drawing is not an engine capture

Stack aliases explain function boundaries. Error stacks or performance samples need not show the same representation: optimization,source maps and async-stack tooling differ. Record which source version matches an observed frame instead of turning three drawn boxes into a native-memory claim.

The await branch lets the caller proceed while an async continuation is deferred. A pending callback is also not guaranteed to run in the same Document for its entire lifetime;navigation and cancellation have separate conditions. This lesson does not simulate every dispatch/lifecycle edge case. Keep findings bounded to the supplied continuation fixture.

3. Blue · Secure development & defense

Read every scenario without motion

Order review

  1. The expected synchronous prefix was tied to source

    The selected synchronous code, Promise reaction, queueMicrotask callback and timer callback produce log labels. expectedLog is the expected order, not the console record of a new execution. A callback label identifies its own completed work; this fixture produces no body-consumption, server-commit or DOM/pixel result. expectedLog starts with script:start, executor and script:end. The executor is synchronous constructor work; the then reaction is a scheduled continuation. The observer distinguishes their roles rather than merging log labels.

    Order ledger
    Synchronous prefix: start/executor/end
    Callback comparison
    Scheduling pending
    Evidence verdict
    Outcome unknown
  2. Checkpoint order was built from finite enqueue order

    promise and microtask are already queued; nested is added inside the microtask. The expected suffix is promise, microtask, nested. This concrete order is the fixture’s dependency, not arbitrary task-source ordering.

    Order ledger
    Synchronous prefix: start/executor/end
    Callback comparison
    Checkpoint: promise/microtask/nested
    Evidence verdict
    Outcome unknown
  3. The timer label was related to queue order

    Timer is the last expected label. Argument 0 is not measured elapsed time. Without DOM or pixel observations, seeing the timer label is not a timestamp of a presented update.

    Order ledger
    Timer after checkpoint / latency unknown
    Callback comparison
    Checkpoint: promise/microtask/nested
    Evidence verdict
    Outcome unknown
  4. Call and await controls checked distinct invariants

    A:start/B/A:end is ordinary synchronous call order. before-await/after-call/after-await separates caller progress from continuation. The traces are not correlated as though they share an identical queue/stack record.

    Order ledger
    Timer after checkpoint / latency unknown
    Callback comparison
    Call trace and await trace separately consistent
    Evidence verdict
    Outcome unknown
  5. Order consistency was not a browser-performance claim

    Finite local callbacks can demonstrate expected ordering without measuring timer latency, rAF relationships, networks, worker concurrency or paint. Correct ordinary ordering does not establish responsiveness or action completion.

    Order ledger
    Timer after checkpoint / latency unknown
    Callback comparison
    Call trace and await trace separately consistent
    Evidence verdict
    Ordering supported / performance unmeasured
  6. Regression was bounded to the needed milestone

    Checks separately verify the synchronous prefix, microtask suffix and await continuation. Missing labels need coverage before cause is inferred. Bounded nonsensitive labels may suffice; application commit needs separate observation.

    Order ledger
    Timer after checkpoint / latency unknown
    Callback comparison
    Call trace and await trace separately consistent
    Evidence verdict
    Recheck prefix/checkpoint/continuation separately

Presentation gap

  1. Log completeness was separated from paint records

    The selected synchronous code, Promise reaction, queueMicrotask callback and timer callback produce log labels. expectedLog is the expected order, not the console record of a new execution. A callback label identifies its own completed work; this fixture produces no body-consumption, server-commit or DOM/pixel result. Seven expected labels are supplied and paintCaptured is false. Knowing callbacks executed does not establish painted or presented text. renderOrderingWithTimer is unspecified in this fixture.

    Order ledger
    Seven expected labels / paint capture absent
    Callback comparison
    Scheduling pending
    Evidence verdict
    Outcome unknown
  2. No guessed ordering was added for timer and rendering

    The ledger places timer after the checkpoint but supplies no universal order between rAF and timers. Boxes in an event-loop animation are not an actual compositor timeline. Rendering-opportunity timing needs its own observation.

    Order ledger
    Seven expected labels / paint capture absent
    Callback comparison
    No rAF/timer order claim
    Evidence verdict
    Outcome unknown
  3. A missing callback event did not explain its cause

    If an alternative trace lacks nested, it does not automatically prove a faulty queue. Logging coverage, selected source and document lifetime are needed separately. The complete fixture log cannot replace the missing observation.

    Order ledger
    Missing label / coverage and lifecycle needed
    Callback comparison
    No rAF/timer order claim
    Evidence verdict
    Outcome unknown
  4. The required completion contract was tied to evidence

    DOM updates need DOM observations, presented pixels need captures and server commit needs server-side records. A Promise-reaction label is not common proof of all three. Review identifies the required outcome first.

    Order ledger
    Missing label / coverage and lifecycle needed
    Callback comparison
    Outcome-specific observations required
    Evidence verdict
    Outcome unknown
  5. Paint and timing verdicts remained unknown

    Exact timer latency and presented pixels remain UNKNOWN. A missing capture does not establish rendering failure; complete callback order does not establish first-pixel success. Observation families remain distinct.

    Order ledger
    Missing label / coverage and lifecycle needed
    Callback comparison
    Outcome-specific observations required
    Evidence verdict
    UNKNOWN: latency and presented pixels
  6. New evidence was requested only within the question’s scope

    Further review needs scoped timestamps and the required DOM/presentation record, not full page data or user identity. Callback-order results are not relabeled as measured timing.

    Order ledger
    Missing label / coverage and lifecycle needed
    Callback comparison
    Outcome-specific observations required
    Evidence verdict
    Needed: scoped timing/presentation observations

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Give async work an explicit completion contract

The selected synchronous code, Promise reaction, queueMicrotask callback and timer callback produce log labels. expectedLog is the expected order, not the console record of a new execution. A callback label identifies its own completed work; this fixture produces no body-consumption, server-commit or DOM/pixel result. Application code should state what each callback completes. Data received,body consumed,validated,DOM updated and server committed are different events. Choose the right completion boundary before advancing UI state. A fulfilled Promise describes the work that Promise represents;additional product-contract work needs its own steps.

The ordinary example separates executor from reaction. Log labels let an observer distinguish job ready from callback processed as two records. That small distinction also makes errors and cancellation easier to explain. This lesson adds no real application request or credential processing;it builds reliable local semantics first.

Evaluate responsiveness and evidence separately

Long main-thread work can delay user interaction and rendering work. An async keyword does not move CPU cost to another thread;bounded work or appropriate worker design needs separate evaluation. This lesson supplies no stall-duration,device-speed or universal-refresh guarantee. Its native fixture uses short,finite callbacks.

Follow the synchronous prefix, microtask order and await continuation by identifying which callback runs at each phase. A completion label must name the completed operation. Resolving a Promise does not mean its dependent reaction executed at that moment; retain task and microtask ordering separately.

NOW APPLY IT TO THE CASE

What distinct completion boundaries belong to executors, microtasks, await continuations and timers?

The finite example starts with script:start, executor and script:end; promise, microtask and nested run at the checkpoint, followed by timer. Await does not prevent caller progress. This order measures neither exact latency, painted pixels nor business commit.

Order response receipt, parsing, callbacks and visible DOM outcome in the case. Try explaining the retained old title through this lesson’s browser-state distinctions.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

Bounded callback-order ledger

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "normalCode": "const log=[];log.push(\"script:start\");new Promise(resolve=>{log.push(\"executor\");resolve();}).then(()=>log.push(\"promise\"));queueMicrotask(()=>{log.push(\"microtask\");queueMicrotask(()=>log.push(\"nested\"));});setTimeout(()=>log.push(\"timer\"),0);log.push(\"script:end\");",
  "expectedLog": [
    "script:start",
    "executor",
    "script:end",
    "promise",
    "microtask",
    "nested",
    "timer"
  ],
  "expectedCallTrace": [
    "A:start",
    "B",
    "A:end"
  ],
  "expectedAwaitTrace": [
    "before-await",
    "after-call",
    "after-await"
  ],
  "executionContextModel": "Instructional specification aliases,not engine memory/stack capture",
  "timerDelayArgument": 0,
  "elapsedMillisecondsExpected": null,
  "microtasksAddedByMicrotask": 1,
  "renderOrderingWithTimer": "unspecified in this fixture",
  "paintCaptured": false,
  "networkExecuted": false
}
expectedLog
Ordering for one ordinary synchronous start and bounded checkpoint.
timerDelayArgument
Scheduling request,not a measured callback execution time.
executionContextModel
Specification aliases,not a native context object accessible to script.
paintCaptured
False:callback ordering does not establish presentation timing.

Ordinary finite browser fixture. No timer-latency,rAF/timer-order,network,engine-memory,worker-concurrency or pixel capture. Scene queues are selected semantic aliases.

Two reality checks

All code inside a Promise runs asynchronously.

The constructor invokes its executor synchronously;the then reaction runs later at an appropriate checkpoint.

A timer0runs immediately,and every task is followed by a paint.

A timer does not interrupt current code;rendering has separate task/opportunity conditions.Ordering is not timing measurement.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

What is the order of the Promise executor, script:end and the .then callback?

  1. promise → executor → script:end; a Promise creates a new thread.
  2. executor → script:end → promise.
Read the explained answer

executor → script:end → promise. — The new Promise executor runs in the current job; the then reaction is processed at a checkpoint after the current script finishes.

Why is setTimeout(..., 0) not evidence of execution at exactly 0 ms here?

Selected lesson artifact fields; teaching example

expectedLog
["script:start","executor","script:end","promise","microtask","nested","timer"]
timerDelayArgument
0
elapsedMillisecondsExpected
null
  1. The timer task follows microtasks in the selected log; elapsed time is not supplied.
  2. Argument 0 guarantees execution in the middle of the script at exactly 0 ms.
Read the explained answer

The timer task follows microtasks in the selected log; elapsed time is not supplied. — elapsedMillisecondsExpected=null; pending jobs/checkpoints and scheduling time remain distinct from the delay argument.

Why does before-await, after-call, after-await ordering not imply a new thread? What does it not establish about paint?

Read the explained answer

await suspends a function continuation and permits the caller to progress; the reaction resumes through later job/microtask scheduling. This trace is not an engine-thread/memory capture. DOM or callback completion supplies no pixels or raf-timer ordering guarantee beyond paintCaptured=false.

□ I did not count continuation scheduling as thread creation.

□ I did not count log order as a paint measurement.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

MANUAL LAB

Browser Observation Lab

Predict Document, DOM/CSS, and event-loop results in 18 fields, record native Browser observations, and explain why.

Open the prediction → observation → explanation workbook ↗Source on GitHub ↗

Sources and scope