Engrain by ByteRush

FND.10.03 Beginner· 8 minCore — asked often

Callbacks and timers: telling JavaScript to do something later

Pass a function to run later, schedule it with setTimeout or setInterval, cancel it, and see why setTimeout(fn, 0) still runs after your other code.

Comes up in: Recruiter screen, JavaScript

Learn#

You place a food order. The app does not freeze while a delivery partner is found; you can still scroll the menu. Somewhere in its code, the app said: “later, when this is ready, run this function.”

In JavaScript a function is a value. You can store it in a variable or hand it to another function, like handing someone a note with instructions.

A function you hand over to be called later is a callback.

A timer is the browser’s alarm clock. setTimeout(callback, ms) runs the callback once, after at least ms milliseconds. setInterval(callback, ms) runs it again and again. Both return an ID; pass it to clearTimeout or clearInterval to cancel. setTimeout on MDN setInterval on MDN

Here is the surprise. Even with a delay of 0, the callback runs after the rest of your code:

console.log("1. Order placed");
setTimeout(() => console.log("3. Delivery partner assigned"), 0);
console.log("2. Payment confirmed");

Output (verified)

1. Order placed
2. Payment confirmed
3. Delivery partner assigned

Code like this is asynchronous: you ask now, it happens later.

JavaScript does one thing at a time. A ready callback waits in a line until the current code finishes; then the event loop runs it Source: HTML Standard: Timers.

Why '3' prints lastStep 1 of 5

Call stack

  • main

Task queue

    empty

    Console

    • 1. Order placed

    JavaScript runs your code from top to bottom. First line: print '1. Order placed'.

    Read the steps as text
    1. JavaScript runs your code from top to bottom. First line: print '1. Order placed'.
    2. setTimeout does not wait. It asks the browser's timer to call your function later, then moves on at once.
    3. Next line runs straight away: print '2. Payment confirmed'.
    4. The timer is done (0 ms), so the callback joins the waiting line. It must wait until the current code finishes.
    5. Your code has finished. Now the event loop takes the waiting callback and runs it.

    Predict#

    Predict first

    What does this print?

    setTimeout(() => console.log("B"), 0);
    console.log("A");
    setTimeout(() => console.log("C"), 0);

    Interview angle#

    Say it like this — about 30 seconds

    “setTimeout never runs its callback in the middle of my code. It hands the callback to a timer and returns at once. When the timer finishes, the callback waits in a queue. JavaScript runs one thing at a time, so the event loop only picks up that callback after the current code has finished. That is why a 0 ms timeout still prints after the lines below it.”

    Stays on your device. Nothing is uploaded.
    Follow-up Is the delay exact?
    No — it is a minimum. The callback can run later if the page is busy, and browsers raise very short delays for deeply nested timers and for background tabs.
    Follow-up How do you stop a setInterval?
    Keep the ID it returns and call clearInterval(id), for example when the countdown reaches zero.
    Follow-up What is a callback?
    A function you pass to other code so that code can call it later, for example when a timer ends or a button is clicked.

    Practice#

    On your own

    Write countdown(n, print): print n, n − 1, … 1, one per second, then Go!, and stop the timer.

    Done when

    • The numbers come one second apart, then “Go!”.
    • No more output after “Go!” — the interval is cleared.
    • countdown(0) prints only “Go!”.
    Your solution
    Ctrl/⌘ + Enter

    Remember#

    Try to answer each card before you open it. Then add them to your reviews.

    What is a callback?

    A function you pass to other code so it can be called later.

    How do you cancel a timer started with setTimeout?

    Pass the ID it returned to clearTimeout.

    What does this print?
    setTimeout(() => console.log("late"), 0);
    console.log("now");
    now
    late
    In 30 seconds: why does setTimeout(fn, 0) run after the code below it?
    • Timer hands the callback over and returns at once
    • Ready callback waits in a queue
    • One thing at a time
    • Event loop runs it after current code

    Go deeper

    Four layers. Stop at the one your interview needs; each ends with a quick check.

    The core ideaEvery round

    Two ideas carry everything: functions are values you can hand over, and a timer calls your function later — never in the middle of code that is already running.

    Check yourself: setTimeout returns before its callback runs. True or false?

    True.

    How it works underneathSenior rounds

    The timer itself is kept by the browser or Node.js, outside your code. When it fires, the callback is added to a task queue. The event loop repeats one step forever: if nothing is running, take the next task and run it to the end. The full picture — microtasks, rendering, Node’s phases — is in JS.01.

    Check yourself: Where does a ready timer callback wait?

    In a task queue, until the event loop picks it.

    Edge cases and trapsWhere people slip

    Delays are minimums, not promises: a busy page or a background tab makes timers late. Nested timers are clamped to a minimum delay by the HTML Standard. Writing setTimeout(fn(), 1000) calls fn immediately and passes its result — pass fn, not fn(). Forgetting clearInterval keeps the callback running forever.

    Check yourself: Why might a 1000 ms interval drift on a busy page?

    Each run can start late, because a callback only runs when the thread is free.

    In productionStaff-level answers

    In real apps, every timer you start must be stopped when its screen goes away, or it leaks memory and runs on stale data — a common React bug (RCT.04). For accurate clocks, compare against the current time instead of counting ticks. For animation, use requestAnimationFrame, not timers (JS.01.04) Source: MDN: setTimeout().

    Check yourself: Name one thing to clean up when a component that started an interval goes away.

    Clear the interval (clearInterval) so it stops running.

    Finished the five steps? Mark it, and its cards join your reviews.

    Last checked 2026-10-31. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.

    Interview questions this answers

    • Why does setTimeout(() => console.log("a"), 0) print after synchronous code?