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('after ');
}, 0);
console.log(' before ');

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

bash
before
after

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

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 = () => {
  // do something
  setTimeout(myFunction, 1000);
};
setTimeout(myFunction, 1000);

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

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