Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чому setTimeout(fn, 0) не виконується одразу?

setTimeout(fn, 0) означає не «виконай зараз», а «постав у чергу, щойно буде можливість». JavaScript у браузері виконується в одному потоці: поки працює поточний код, ніщо інше не запуститься.

console.log('1');
setTimeout(() => console.log('3'), 0);
Promise.resolve().then(() => console.log('2б'));
console.log('2');
// 1, 2, 2б, 3

Порядок такий:

  1. виконується весь синхронний код до кінця;
  2. виконуються всі мікрозадачі (колбеки Promise, queueMicrotask);
  3. браузер може перемалювати сторінку;
  4. береться наступна макрозадача - зокрема колбек таймера.

Тому колбек Promise спрацьовує раніше за таймер з нульовою затримкою.

Затримка - мінімальна, а не точна. setTimeout(fn, 100) гарантує лише, що колбек запуститься не раніше ніж за 100 мс. Якщо головний потік зайнятий важким обчисленням 2 секунди, таймер спрацює через 2 секунди.

Інші обмеження:

  • вкладені таймери після п'яти рівнів отримують мінімальну затримку 4 мс;
  • у фонових вкладках браузер пригальмовує таймери до разу на секунду і рідше - не можна покладатися на них для точного відліку часу;
  • для анімацій є requestAnimationFrame, синхронізований з перемальовуванням екрана.

Навіщо setTimeout(fn, 0) на практиці: відкласти роботу до моменту, коли поточна подія оброблена й DOM оновлено, або розбити довгу роботу на шматки, даючи браузеру перемальовувати сторінку між ними.

Докладніше в документації: setTimeout()

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання