Skip to main content

setTimeout(fn, 0)

Короткий відповідь

setTimeout(fn, 0) не виконує функцію миттєво. Він просто ставить колбек fn у чергу макротасок, щоб він виконався після завершення поточного коду і всіх мікротасок.

Приклад

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

Вивід:

javascript
A C B

Чому не A -> B -> C?

Що відбувається крок за кроком

  1. console.log('A') - виконується одразу (у Call Stack).
  2. setTimeout(() => console.log('B'), 0) - передає задачу у Web API (таймер із затримкою 0 мс).
  3. Таймер миттєво "спрацьовує", і колбек додається в чергу макротасок.
  4. JS продовжує виконувати поточний стек (console.log('C')).
  5. Коли стек викликів порожній, Event Loop бере задачу () => console.log('B') із черги і виконує її.

Чому навіть 0 не виконується одразу

Тому що в JavaScript усе працює через Event Loop, і він ніколи не перериває поточний стек викликів.

Навіть якщо затримка 0, колбек все одно повинен зачекати, поки стек звільниться.

Тобто setTimeout(fn, 0) - це спосіб відкласти виконання функції до наступної ітерації Event Loop.

Приклад з promise (мікротаска)

javascript
setTimeout(() => console.log('timeout'), 0); Promise.resolve().then(() => console.log('promise')); console.log('end');

Порядок:

javascript
end promise timeout

Пояснення:

  • Promise.then() створює мікротаску,
  • setTimeout() - макротаску,
  • а мікротаски завжди виконуються раніше, ніж макротаски.

Практичне застосування

  1. Відкласти виконання, щоб не блокувати основний код:
javascript
setTimeout(() => { console.log('Виконається після основного коду'); }, 0);
  1. Розірвати синхронний цикл, щоб UI встиг оновитися:
javascript
for (let i = 0; i < 1e9; i++) {} // важка операція console.log('UI завис...'); setTimeout(() => { console.log('Тепер виконуємось після паузи'); }, 0);
  1. Скинути стек (наприклад, у рекурсивних обчисленнях):
javascript
function nextStep() { setTimeout(nextStep, 0); // кожне повторення - нова ітерація Event Loop } nextStep();

Підсумок

ПараметрЗначення
Що робитьСтавить колбек у чергу макротасок
Коли виконуєтьсяПісля поточного стеку і всіх мікротасок
Затримка "0"Не миттєво, а в наступному циклі Event Loop
ЧергаМакротаски
ПовертаєID таймера (можна скасувати через clearTimeout)

Візуально

javascript
[Call Stack] → виконується поточний код [Microtask Queue] → promise та queueMicrotask [Task Queue] → setTimeout(fn, 0)

setTimeout(fn, 0) завжди чекає, поки:

  1. стек викликів очиститься,
  2. мікротаски виконаються,
  3. і лише потім - виконується fn.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.