Таймеры
Таймер позволяет выполнить код не сейчас, а через какое-то время, или повторять его через равные промежутки. С таймерами делают напоминания, автосохранение, обратный отсчёт и паузы между действиями.
setTimeout
Функция setTimeout() вызывает переданную функцию один раз через заданное число миллисекунд. В одной секунде 1000 миллисекунд:
setTimeout(() => {
console.log('Прошло полсекунды');
}, 500);
// Прошло полсекундыПервый аргумент — что выполнить, второй — задержка. Функцию, которую передают другой функции, чтобы та вызвала её позже, называют колбэком.
Код не ждёт таймер
setTimeout() только ставит таймер и сразу возвращает управление. Код после него выполняется раньше, чем функция из таймера:
console.log('Первый');
setTimeout(() => {
console.log('Третий');
}, 300);
console.log('Второй');
// Первый
// Второй
// ТретийПочему так происходит, объясняет цикл событий из предыдущего урока.
Функция по имени и аргументы
Вместо стрелочной функции можно передать готовую функцию по имени — без скобок. Аргументы для неё перечисляют после задержки:
function greet(name) {
console.log(`Привет, ${name}!`);
}
setTimeout(greet, 300, 'Анна');
// Привет, Анна!Отмена таймера
setTimeout() возвращает идентификатор — номер таймера. Если передать его в clearTimeout(), функция не выполнится:
const timer = setTimeout(() => {
console.log('Это не выведется');
}, 500);
clearTimeout(timer);
console.log('Таймер отменён'); // Таймер отменёнТак отменяют, например, автосохранение, если пользователь закрыл форму раньше.
setInterval
setInterval() вызывает функцию снова и снова через равные промежутки. Останавливает его clearInterval() с идентификатором интервала:
let count = 0;
const timer = setInterval(() => {
count++;
console.log(`Тик ${count}`);
if (count === 3) {
clearInterval(timer);
}
}, 200);
// Тик 1
// Тик 2
// Тик 3Задержка — это минимум
Таймер гарантирует, что функция выполнится не раньше указанного времени, но может выполниться и позже, если JavaScript занят другим кодом:
const start = Date.now();
setTimeout(() => {
console.log(Date.now() - start >= 100); // true
}, 100);Поэтому таймеры не подходят для точного отсчёта времени. Для часов на странице каждый раз берут текущее время через Date.now().
Частая ошибка
Передать в таймер не функцию, а результат её вызова. Запись setTimeout(greet('Анна'), 1000) выполнит greet сразу, а таймеру достанется undefined. Правильно — передать саму функцию: setTimeout(() => greet('Анна'), 1000). И не забывайте останавливать интервалы: забытый setInterval() работает, пока открыта вкладка.