Skip to content

Изучаем таймеры JavaScript

setTimeout()

При написании кода JavaScript может возникнуть необходимость отложить выполнение функции.

Для этого предназначен setTimeout. Вы указываете функцию обратного вызова, которая будет выполнена позже, и значение, указывающее, насколько позже она должна быть запущена, в миллисекундах:

js
setTimeout(() => {
  // выполняется через 2 секунды
}, 2000)
setTimeout(() => {
  // выполняется через 50 миллисекунд
}, 50)

Этот синтаксис определяет новую функцию. Вы можете вызывать там любую другую функцию, или можете передать имя существующей функции и набор параметров:

js
const myFunction = (firstParam, secondParam) => {
  // сделать что-то
}
// выполняется через 2 секунды
setTimeout(myFunction, 2000, firstParam, secondParam)

setTimeout возвращает идентификатор таймера. Обычно он не используется, но вы можете сохранить этот идентификатор и очистить его, если хотите удалить запланированное выполнение этой функции:

js
const id = setTimeout(() => {
  // должно выполниться через 2 секунды
}, 2000)
// передумал
clearTimeout(id)

Нулевая задержка

Если вы указываете задержку таймера равную 0, функция обратного вызова будет выполнена как можно скорее, но после завершения выполнения текущей функции:

js
setTimeout(() => {
  console.log('после ')
}, 0)
console.log(' до ')

Этот код выведет

bash
до
после

Это особенно полезно для того, чтобы избежать блокировки ЦП при выполнении ресурсоемких задач и позволить другим функциям выполняться во время выполнения сложных вычислений, путем помещения функций в очередь планировщика.

TIP

Некоторые браузеры (IE и Edge) реализуют метод setImmediate(), который выполняет ту же самую функциональность, но он не является стандартным и недоступен в других браузерах. Но это стандартная функция в Node.js.

setInterval()

setInterval — это функция, аналогичная setTimeout, с одним отличием: вместо однократного выполнения функции обратного вызова она будет выполнять ее бесконечно, через указанный вами интервал времени (в миллисекундах):

js
setInterval(() => {
  // выполняется каждые 2 секунды
}, 2000)

Функция выше выполняется каждые 2 секунды, пока вы не укажете ей остановиться, используя clearInterval, передавая ей идентификатор интервала, возвращаемый setInterval:

js
const id = setInterval(() => {
  // выполняется каждые 2 секунды
}, 2000)
// передумал
clearInterval(id)

Обычно clearInterval вызывается внутри функции обратного вызова setInterval, чтобы позволить ей автоматически определить, следует ли ей выполняться снова или остановиться. Например, этот код выполняет что-то, пока App.somethingIWait не получит значение arrived:

Рекурсивный setTimeout

setInterval запускает функцию каждые n миллисекунд, не учитывая, когда функция завершила своё выполнение.

Если функция всегда занимает одинаковое время, всё в порядке.

Возможно, функция занимает разное время выполнения в зависимости от сетевых условий.

И, возможно, одно длительное выполнение перекрывает следующее.

Чтобы избежать этого, можно запланировать рекурсивный setTimeout, который будет вызываться по завершении функции обратного вызова:

js
const myFunction = () => {
  // выполнить что-либо
  setTimeout(myFunction, 1000)
}
setTimeout(myFunction, 1000)

setTimeout и setInterval доступны в Node.js через модуль Timers.

Node.js также предоставляет setImmediate(), который эквивалентен использованию setTimeout(() => {}, 0), в основном используется для работы с циклом событий Node.js.