Що робить і що повертає setTimeout()
setTimeout() це функція планування задач: вона реєструє колбек у зовнішньому API середовища, запускає таймер і після його спрацювання ставить колбек у чергу макрозадач. Повертає вона ідентифікатор таймера, за яким виконання можна скасувати через clearTimeout().
Теорія
TL;DR
setTimeoutпланує одноразове виконання функції через задану затримку.- Сам таймер веде не рушій JavaScript, а Web API браузера або Timer API Node.js.
- Після спрацювання таймера колбек потрапляє в чергу макрозадач, а не виконується одразу.
- Затримка це мінімум: колбек чекає, доки звільниться стек викликів.
- Повертається ідентифікатор таймера для
clearTimeout().
Швидкий приклад
console.log('Start');
setTimeout(() => {
console.log('after 2 seconds');
}, 2000);
console.log('End');Порядок виконання:
Start
End
after 2 secondsЧому так:
- JavaScript спершу виконує весь синхронний код.
setTimeoutлише планує задачу.- Через 2000 мс колбек потрапляє в чергу задач.
- Коли стек порожній, event loop виконує колбек.
Що робить setTimeout
- Реєструє колбек (функцію) у Web API або Node.js Timer API.
- Запускає таймер на заданий час у мілісекундах.
- Після завершення цього часу додає колбек у чергу макрозадач (task queue).
- Колбек буде виконано лише тоді, коли стек викликів звільниться.
Синтаксис:
setTimeout(callback, delay, ...args);Параметри:
callbackце функція, яку потрібно виконати;delayце затримка в мілісекундах, вона не гарантує точного часу;...argsце додаткові аргументи, які буде передано вcallback.
Що повертає setTimeout
Функція повертає ідентифікатор таймера, унікальне значення, за яким можна скасувати виконання через clearTimeout().
const timerId = setTimeout(() => {
console.log('I will not make it');
}, 5000);
clearTimeout(timerId); // cancel the timerПісля виклику clearTimeout(timerId) колбек ніколи не виконається.
Деталь середовища: у браузері це ціле число, у Node.js це об'єкт Timeout. В обох випадках значення просто передають у clearTimeout(), покладатися на його тип не варто.
Важливі деталі
Мінімальна затримка
Навіть setTimeout(..., 0) не виконується миттєво:
setTimeout(() => console.log('B'), 0);
console.log('A');Вивід:
A
BБо навіть із delay = 0 колбек додається в чергу макрозадач і виконується лише після звільнення стека та всіх мікрозадач (Promise.then і подібних).
Не гарантує точного часу
Якщо 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, бо стек був зайнятий.
Можна передавати аргументи
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 мс.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.