Мы можем вызвать функцию не в данный момент, а позже, через заданный интервал времени. Это называется «планирование вызова».
Для этого существуют два метода:
- setTimeout позволяет вызвать функцию один раз через определённый интервал времени.
- setInterval позволяет вызывать функцию регулярно, повторяя вызов через определённый интервал времени.
setTimeout
Синтаксис: let timerId = setTimeout(func|code, [delay], [arg1], [arg2], ...);
Параметры:
func|code Функция или строка кода для выполнения. Обычно это функция. По историческим причинам можно передать и строку кода, но это не рекомендуется.
delay Задержка перед запуском в миллисекундах (1000 мс = 1 с). Значение по умолчанию – 0.
arg1, arg2… Аргументы, передаваемые в функцию
Например, данный код вызывает sayHi() спустя одну секунду:
function sayHi() {
alert("Привет")
}
setTimeout(sayHi, 1000)С аргументами:
function sayHi(phrase, who) {
alert(phrase + ", " + who)
}
_
setTimeout(sayHi, 1000, "Привет", "Джон") // Привет, Джон_`Если первый аргумент является строкой, то JavaScript создаст из неё функцию.
setInterval
Метод setInterval имеет такой же синтаксис как setTimeout:
let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...);
Все аргументы имеют такое же значение. Но отличие этого метода от setTimeout в том, что функция запускается не один раз, а периодически через указанный интервал времени.
Рекурсивный setTimeout
Применение вложенного setTimeout:
let i = 1
setTimeout(function run() {
func(i)
setTimeout(run, 100)
}, 100)Ниже представлено изображение, показывающее процесс работы рекурсивного setTimeout:

ВложенныйsetTimeout гарантирует фиксированную задержку (здесь 100 мс).
Это потому, что новый вызов планируется в конце предыдущего.
Отличие setInterval и рекурсивного setTimeout
Применение setInterval:
let i = 1;
setInterval(function() {
func(i); }, 100);`Для setInterval внутренний планировщик будет выполнять func(i) каждые 100 мс:
Реальная задержка между вызовами func с помощью setInterval меньше, чем указано в коде!
Это нормально, потому что время, затраченное на выполнение func, использует часть заданного интервала времени.
Вполне возможно, что выполнение func будет дольше, чем мы ожидали, и займёт более 100 мс.
В данном случае движок ждёт окончания выполнения func и затем проверяет планировщик и, если время истекло, немедленно запускает его снова.
Как отменять таймеры и зачем это нужно?
Вызов setTimeout возвращает «идентификатор таймера» timerId, который можно использовать для отмены дальнейшего выполнения.
Синтаксис для отмены:
let timerId = setTimeout(...); clearTimeout(timerId);
В коде ниже планируем вызов функции и затем отменяем его (просто передумали). В результате ничего не происходит:
let timerId = setTimeout(() => alert("ничего не происходит"), 1000)
alert(timerId) // идентификатор таймера
clearTimeout(timerId)
alert(timerId) // тот же идентификатор (не принимает значение null после отмены)`Как мы видим из вывода alert, в браузере идентификатором таймера является число. В других средах это может быть что-то ещё. Например, Node.js возвращает объект таймера с дополнительными методами.
Повторюсь, что нет единой спецификации на эти методы, поэтому такое поведение является нормальным.
Для браузеров таймеры описаны в разделе таймеров стандарта HTML5.