Skip to main content

Що робить і що повертає setTimeout()

setTimeout() це функція планування задач: вона реєструє колбек у зовнішньому API середовища, запускає таймер і після його спрацювання ставить колбек у чергу макрозадач. Повертає вона ідентифікатор таймера, за яким виконання можна скасувати через clearTimeout().

Теорія

TL;DR

  • setTimeout планує одноразове виконання функції через задану затримку.
  • Сам таймер веде не рушій JavaScript, а Web API браузера або Timer API Node.js.
  • Після спрацювання таймера колбек потрапляє в чергу макрозадач, а не виконується одразу.
  • Затримка це мінімум: колбек чекає, доки звільниться стек викликів.
  • Повертається ідентифікатор таймера для clearTimeout().

Швидкий приклад

javascript
console.log('Start'); setTimeout(() => { console.log('after 2 seconds'); }, 2000); console.log('End');

Порядок виконання:

javascript
Start End after 2 seconds

Чому так:

  • JavaScript спершу виконує весь синхронний код.
  • setTimeout лише планує задачу.
  • Через 2000 мс колбек потрапляє в чергу задач.
  • Коли стек порожній, event loop виконує колбек.

Що робить setTimeout

  1. Реєструє колбек (функцію) у Web API або Node.js Timer API.
  2. Запускає таймер на заданий час у мілісекундах.
  3. Після завершення цього часу додає колбек у чергу макрозадач (task queue).
  4. Колбек буде виконано лише тоді, коли стек викликів звільниться.

Синтаксис:

javascript
setTimeout(callback, delay, ...args);

Параметри:

  • callback це функція, яку потрібно виконати;
  • delay це затримка в мілісекундах, вона не гарантує точного часу;
  • ...args це додаткові аргументи, які буде передано в callback.

Що повертає setTimeout

Функція повертає ідентифікатор таймера, унікальне значення, за яким можна скасувати виконання через clearTimeout().

javascript
const timerId = setTimeout(() => { console.log('I will not make it'); }, 5000); clearTimeout(timerId); // cancel the timer

Після виклику clearTimeout(timerId) колбек ніколи не виконається.

Деталь середовища: у браузері це ціле число, у Node.js це об'єкт Timeout. В обох випадках значення просто передають у clearTimeout(), покладатися на його тип не варто.

Важливі деталі

Мінімальна затримка

Навіть setTimeout(..., 0) не виконується миттєво:

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

Вивід:

javascript
A B

Бо навіть із delay = 0 колбек додається в чергу макрозадач і виконується лише після звільнення стека та всіх мікрозадач (Promise.then і подібних).

Не гарантує точного часу

Якщо JavaScript зайнятий іншою функцією, таймер «запізниться»:

javascript
setTimeout(() => console.log('I am late!'), 1000); const start = Date.now(); while (Date.now() - start < 5000) {} // block the thread for 5 seconds

Колбек спрацює через 5 секунд, а не через 1, бо стек був зайнятий.

Можна передавати аргументи

javascript
setTimeout((a, b) => { console.log(a + b); }, 1000, 5, 7); // prints 12 after one second

Підсумок

Що робитьЩо повертаєДе виконуєтьсяЧерга
Планує виконання функції через задану затримкуІдентифікатор таймераУ Web API (браузер) або Node Timer APIМакрозадачі (task queue)
Можна скасуватиclearTimeout(timerId)

Типові помилки

  • Вважати, що delay це точний час. Це мінімальна затримка, реальна залежить від завантаженості стека.
  • Думати, що setTimeout(fn, 0) виконається раніше за Promise.then. Мікрозадачі завжди мають пріоритет над макрозадачами.
  • Викликати колбек одразу: setTimeout(fn(), 1000) замість setTimeout(fn, 1000). У першому випадку планується результат виклику, а не сама функція.
  • Втрачати ідентифікатор таймера і потім не мати змоги скасувати задачу через clearTimeout().
  • Плутати з setInterval: setTimeout спрацьовує один раз, повторення треба планувати самому.
  • Розраховувати, що у вкладених таймерах затримка лишиться нульовою. Браузери після п'ятого рівня вкладеності примусово піднімають мінімум приблизно до 4 мс.

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

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

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