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