Мы можем вызвать функцию не в данный момент, а позже, через заданный интервал времени. Это называется «планирование вызова».

Для этого существуют два метода:

  • setTimeout позволяет вызвать функцию один раз через определённый интервал времени.
  • setInterval  позволяет вызывать функцию регулярно, повторяя вызов через определённый интервал времени.
setTimeout

Синтаксис: let timerId = setTimeout(func|code, [delay], [arg1], [arg2], ...);

Параметры: func|code Функция или строка кода для выполнения. Обычно это функция. По историческим причинам можно передать и строку кода, но это не рекомендуется.

delay Задержка перед запуском в миллисекундах (1000 мс = 1 с). Значение по умолчанию – 0.

arg1arg2… Аргументы, передаваемые в функцию

Например, данный код вызывает 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.


Назад