What setTimeout() does and returns
setTimeout() is a task scheduling function: it registers a callback with the environment's external API, starts a timer, and once the timer fires, puts the callback into the macrotask queue. It returns a timer identifier that you can use to cancel the execution with clearTimeout().
Theory
TL;DR
setTimeoutschedules a one time execution of a function after a given delay.- The timer itself is run not by the JavaScript engine but by the browser's Web API or the Node.js Timer API.
- After the timer fires, the callback enters the macrotask queue, it does not run immediately.
- The delay is a minimum: the callback waits until the call stack is free.
- It returns a timer identifier for
clearTimeout().
Quick example
console.log('Start');
setTimeout(() => {
console.log('after 2 seconds');
}, 2000);
console.log('End');Execution order:
Start
End
after 2 secondsWhy:
- JavaScript first runs all the synchronous code.
setTimeoutonly schedules the task.- After 2000 ms the callback enters the task queue.
- When the stack is empty, the event loop runs the callback.
What setTimeout does
- Registers the callback (a function) with the Web API or the Node.js Timer API.
- Starts a timer for the given time in milliseconds.
- Once that time is up, it adds the callback to the macrotask queue (task queue).
- The callback runs only when the call stack becomes free.
Syntax:
setTimeout(callback, delay, ...args);Parameters:
callbackis the function to run;delayis the delay in milliseconds, it does not guarantee exact timing;...argsare extra arguments passed to thecallback.
What setTimeout returns
The function returns a timer identifier, a unique value you can use to cancel the execution with clearTimeout().
const timerId = setTimeout(() => {
console.log('I will not make it');
}, 5000);
clearTimeout(timerId); // cancel the timerAfter clearTimeout(timerId) the callback never runs.
An environment detail: in the browser it is an integer, in Node.js it is a Timeout object. In both cases you simply pass the value to clearTimeout() and should not rely on its type.
Important details
Minimum delay
Even setTimeout(..., 0) does not run instantly:
setTimeout(() => console.log('B'), 0);
console.log('A');Output:
A
BBecause even with delay = 0 the callback is added to the macrotask queue and runs only after the stack is clear and all microtasks (Promise.then and the like) have run.
It does not guarantee exact timing
If JavaScript is busy running another function, the timer is "late":
setTimeout(() => console.log('I am late!'), 1000);
const start = Date.now();
while (Date.now() - start < 5000) {} // block the thread for 5 secondsThe callback fires after 5 seconds, not after 1, because the stack was busy.
You can pass arguments
setTimeout((a, b) => {
console.log(a + b);
}, 1000, 5, 7);
// prints 12 after one secondSummary
| What it does | What it returns | Where it runs | Queue |
|---|---|---|---|
| Schedules a function to run after a given delay | A timer identifier | In the Web API (browser) or the Node Timer API | Macrotasks (task queue) |
| Can be cancelled | clearTimeout(timerId) |
Common mistakes
- Treating
delayas exact timing. It is a minimum delay, the real one depends on how busy the stack is. - Expecting
setTimeout(fn, 0)to run beforePromise.then. Microtasks always take priority over macrotasks. - Calling the callback right away:
setTimeout(fn(), 1000)instead ofsetTimeout(fn, 1000). The first form schedules the call's result, not the function. - Losing the timer identifier and then having no way to cancel the task with
clearTimeout(). - Confusing it with
setInterval:setTimeoutfires once, repetition is something you schedule yourself. - Assuming nested timers keep a zero delay. After the fifth level of nesting browsers clamp the minimum to about 4 ms.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.