setTimeout(fn, delay, ...args) calls fn(...args) once after at least delay milliseconds; setInterval() repeats the call every interval. Both return an ID for clearTimeout() or clearInterval(); neither blocks: your remaining code runs first, and each callback joins a task queue when its time comes (Callbacks and the Event Loop).
const start = Date.now();
const log = (msg) => console.log(`${Math.round((Date.now() - start) / 100) * 100} ms: ${msg}`);
setTimeout(log, 500, "timeout 500"); // extra arguments go to the callback
clearTimeout(setTimeout(log, 300, "never")); // cancelled before it fires
let ticks = 0;
const id = setInterval(() => {
log(`tick ${++ticks}`);
if (ticks === 2) clearInterval(id); // stop after two runs
}, 300);
log("synchronous code first");0 ms: synchronous code first 300 ms: tick 1 500 ms: timeout 500 600 ms: tick 2
The delay is a minimum: a busy main thread postpones callbacks, browsers clamp deeply nested timers to 4 ms and throttle background tabs, and delays above 2,147,483,647 ms overflow. Animate with requestAnimationFrame() (requestAnimationFrame).