Перейти к содержанию

Таймеры

latest

Стабильность: 2 – Стабильная

API является удовлетворительным. Совместимость с npm имеет высший приоритет и не будет нарушена, кроме случаев явной необходимости.

Модуль таймеров предоставляет глобальный API для планирования вызова функций в будущем. Поскольку функции таймеров являются глобальными, для использования API не нужно вызывать require('node:timers').

Функции таймеров в Node.js реализуют API, похожий на API таймеров в веб-браузерах, но с другой внутренней реализацией, построенной вокруг цикла событий Node.js.

Класс: Immediate

Этот объект создаётся внутри и возвращается из setImmediate(). Его можно передать в clearImmediate(), чтобы отменить запланированные действия.

По умолчанию, когда планируется немедленный вызов, цикл событий Node.js продолжает работу, пока объект Immediate активен. Объект Immediate, возвращаемый setImmediate(), предоставляет функции immediate.ref() и immediate.unref(), которыми можно управлять этим поведением по умолчанию.

immediate.hasRef()

Если true, объект Immediate удерживает цикл событий Node.js активным.

immediate.ref()

  • Возвращает: <Immediate> ссылку на immediate

При вызове запрашивается, чтобы цикл событий Node.js не завершался, пока активен Immediate. Повторные вызовы immediate.ref() не дают дополнительного эффекта.

По умолчанию все объекты Immediate удерживают цикл событий активным, поэтому обычно не нужно вызывать immediate.ref(), если ранее не вызывали immediate.unref().

immediate.unref()

  • Возвращает: <Immediate> ссылку на immediate

При вызове активный объект Immediate не требует, чтобы цикл событий Node.js оставался активным. Если ничто другое не удерживает цикл событий, процесс может завершиться до вызова обратного вызова Immediate. Повторные вызовы immediate.unref() не дают дополнительного эффекта.

immediate[Symbol.dispose]()

История
Версия Изменения
v24.2.0 Больше не экспериментально.

Отменяет объект Immediate. Аналогично вызову clearImmediate().

Класс: Timeout

Этот объект создаётся внутри и возвращается из setTimeout() и setInterval(). Его можно передать в clearTimeout() или clearInterval(), чтобы отменить запланированные действия.

По умолчанию, когда таймер планируется через setTimeout() или setInterval(), цикл событий Node.js продолжает работу, пока таймер активен. Каждый возвращаемый этими функциями объект Timeout предоставляет timeout.ref() и timeout.unref() для управления этим поведением.

timeout.close()

Стабильность: 3 – Закрыто

Принимаются только исправления, связанные с безопасностью, производительностью или ошибками. Пожалуйста, не предлагайте изменений API в разделе с таким индикатором, они будут отклонены.

Используйте clearTimeout() вместо этого.

  • Возвращает: <Timeout> ссылку на timeout

Отменяет таймаут.

timeout.hasRef()

Если true, объект Timeout удерживает цикл событий Node.js активным.

timeout.ref()

  • Возвращает: <Timeout> ссылку на timeout

При вызове запрашивается, чтобы цикл событий Node.js не завершался, пока активен Timeout. Повторные вызовы timeout.ref() не дают дополнительного эффекта.

По умолчанию все объекты Timeout удерживают цикл событий активным, поэтому обычно не нужно вызывать timeout.ref(), если ранее не вызывали timeout.unref().

timeout.refresh()

  • Возвращает: <Timeout> ссылку на timeout

Устанавливает время старта таймера на текущее и перепланирует вызов обратного вызова через ранее заданную длительность, скорректированную относительно текущего времени. Полезно для обновления таймера без выделения нового объекта JavaScript.

Если вызвать для таймера, который уже отработал обратный вызов, таймер снова активируется.

timeout.unref()

  • Возвращает: <Timeout> ссылку на timeout

При вызове активный объект Timeout не требует, чтобы цикл событий Node.js оставался активным. Если ничто другое не удерживает цикл событий, процесс может завершиться до вызова обратного вызова Timeout. Повторные вызовы timeout.unref() не дают дополнительного эффекта.

timeout[Symbol.toPrimitive]()

  • Возвращает: <integer> число, по которому можно ссылаться на этот timeout

Приводит Timeout к примитиву. Примитив можно использовать для очистки Timeout. Примитив можно использовать только в том же потоке, где создан таймер. Поэтому для использования в worker_threads его нужно сначала передать в нужный поток. Это улучшает совместимость с браузерными реализациями setTimeout() и setInterval().

timeout[Symbol.dispose]()

История
Версия Изменения
v24.2.0 Больше не экспериментально.

Отменяет таймаут.

Планирование таймеров

Таймер в Node.js — внутренняя сущность, вызывающая заданную функцию через некоторое время. Когда именно вызывается функция таймера, зависит от способа создания таймера и от другой работы цикла событий Node.js.

setImmediate(callback[, ...args])

Добавлено в: v0.9.1

История
Версия Изменения
v18.0.0 При передаче недопустимого обратного вызова в аргумент callback теперь выдается ERR_INVALID_ARG_TYPE вместо ERR_INVALID_CALLBACK.

Планирует «немедленный» вызов callback после обратных вызовов событий ввода-вывода.

При нескольких вызовах setImmediate() функции callback ставятся в очередь в порядке создания. Вся очередь обрабатывается на каждой итерации цикла событий. Если объект Immediate ставится в очередь из выполняющегося обратного вызова, он сработает только на следующей итерации цикла событий.

Если callback не является функцией, будет выброшен TypeError.

Для промисов есть отдельный вариант: timersPromises.setImmediate().

setInterval(callback[, delay[, ...args]])

Добавлено в: v0.0.1

История
Версия Изменения
v18.0.0 При передаче недопустимого обратного вызова в аргумент callback теперь выдается ERR_INVALID_ARG_TYPE вместо ERR_INVALID_CALLBACK.
  • callback <Function> Функция, вызываемая при срабатывании таймера.
  • delay <number> Задержка в миллисекундах перед вызовом callback. По умолчанию: 1.
  • ...args <any> Необязательные аргументы для вызова callback.
  • Возвращает: <Timeout> для использования с clearInterval()

Планирует периодический вызов callback каждые delay миллисекунд.

Если delay больше 2147483647, меньше 1 или NaN, delay устанавливается в 1. Нецелые задержки усекаются до целого.

Если callback не является функцией, будет выброшен TypeError.

Для промисов есть отдельный вариант: timersPromises.setInterval().

setTimeout(callback[, delay[, ...args]])

Добавлено в: v0.0.1

История
Версия Изменения
v18.0.0 При передаче недопустимого обратного вызова в аргумент callback теперь выдается ERR_INVALID_ARG_TYPE вместо ERR_INVALID_CALLBACK.
  • callback <Function> Функция, вызываемая при срабатывании таймера.
  • delay <number> Задержка в миллисекундах перед вызовом callback. По умолчанию: 1.
  • ...args <any> Необязательные аргументы для вызова callback.
  • Возвращает: <Timeout> для использования с clearTimeout()

Планирует однократный вызов callback через delay миллисекунд.

callback вряд ли будет вызван ровно через delay миллисекунд. Node.js не гарантирует точное время и порядок срабатывания обратных вызовов. Вызов будет максимально близок к указанному времени.

Если delay больше 2147483647, меньше 1 или NaN, delay устанавливается в 1. Нецелые задержки усекаются до целого.

Если callback не является функцией, будет выброшен TypeError.

Для промисов есть отдельный вариант: timersPromises.setTimeout().

Отмена таймеров

Методы setImmediate(), setInterval() и setTimeout() возвращают объекты, представляющие запланированные таймеры. Их можно использовать для отмены и предотвращения срабатывания.

Для промисных вариантов setImmediate() и setTimeout() для отмены можно использовать AbortController. При отмене возвращаемые промисы отклоняются с 'AbortError'.

Для setImmediate():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { setImmediate as setImmediatePromise } from 'node:timers/promises';

const ac = new AbortController();
const signal = ac.signal;

// Не ждём промис, чтобы `ac.abort()` выполнился параллельно.
setImmediatePromise('foobar', { signal })
  .then(console.log)
  .catch((err) => {
    if (err.name === 'AbortError')
      console.error('The immediate was aborted');
  });

ac.abort();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const { setImmediate: setImmediatePromise } = require('node:timers/promises');

const ac = new AbortController();
const signal = ac.signal;

setImmediatePromise('foobar', { signal })
  .then(console.log)
  .catch((err) => {
    if (err.name === 'AbortError')
      console.error('The immediate was aborted');
  });

ac.abort();

Для setTimeout():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { setTimeout as setTimeoutPromise } from 'node:timers/promises';

const ac = new AbortController();
const signal = ac.signal;

// Не ждём промис, чтобы `ac.abort()` выполнился параллельно.
setTimeoutPromise(1000, 'foobar', { signal })
  .then(console.log)
  .catch((err) => {
    if (err.name === 'AbortError')
      console.error('The timeout was aborted');
  });

ac.abort();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const { setTimeout: setTimeoutPromise } = require('node:timers/promises');

const ac = new AbortController();
const signal = ac.signal;

setTimeoutPromise(1000, 'foobar', { signal })
  .then(console.log)
  .catch((err) => {
    if (err.name === 'AbortError')
      console.error('The timeout was aborted');
  });

ac.abort();

clearImmediate(immediate)

Отменяет объект Immediate, созданный setImmediate().

clearInterval(timeout)

Отменяет объект Timeout, созданный setInterval().

clearTimeout(timeout)

Отменяет объект Timeout, созданный setTimeout().

API таймеров на промисах

Добавлено в: v15.0.0

История
Версия Изменения
v16.0.0 Окончил экспериментальный.

API timers/promises предоставляет альтернативный набор функций таймеров, возвращающих объекты Promise. Доступ через require('node:timers/promises').

1
2
3
4
5
import {
  setTimeout,
  setImmediate,
  setInterval,
} from 'node:timers/promises';
1
2
3
4
5
const {
  setTimeout,
  setImmediate,
  setInterval,
} = require('node:timers/promises');

timersPromises.setTimeout([delay[, value[, options]]])

  • delay <number> Задержка в миллисекундах перед выполнением промиса. По умолчанию: 1.
  • value <any> Значение, с которым выполняется промис.
  • options <Object>
  • ref <boolean> Если false, запланированный Timeout не удерживает цикл событий Node.js активным. По умолчанию: true.
  • signal <AbortSignal> Необязательный AbortSignal для отмены запланированного Timeout.
1
2
3
4
5
6
7
import {
  setTimeout,
} from 'node:timers/promises';

const res = await setTimeout(100, 'result');

console.log(res);  // Prints 'result'
1
2
3
4
5
6
7
const {
  setTimeout,
} = require('node:timers/promises');

setTimeout(100, 'result').then((res) => {
  console.log(res);  // Prints 'result'
});

timersPromises.setImmediate([value[, options]])

  • value <any> Значение, с которым выполняется промис.
  • options <Object>
  • ref <boolean> Если false, запланированный Immediate не удерживает цикл событий Node.js активным. По умолчанию: true.
  • signal <AbortSignal> Необязательный AbortSignal для отмены запланированного Immediate.
1
2
3
4
5
6
7
import {
  setImmediate,
} from 'node:timers/promises';

const res = await setImmediate('result');

console.log(res);  // Prints 'result'
1
2
3
4
5
6
7
const {
  setImmediate,
} = require('node:timers/promises');

setImmediate('result').then((res) => {
  console.log(res);  // Prints 'result'
});

timersPromises.setInterval([delay[, value[, options]]])

Возвращает асинхронный итератор, выдающий значения с интервалом delay мс. Если ref равен true, нужно явно или неявно вызывать next() у асинхронного итератора, чтобы цикл событий оставался активным.

  • delay <number> Интервал в миллисекундах между итерациями. По умолчанию: 1.
  • value <any> Значение, которое возвращает итератор.
  • options <Object>
  • ref <boolean> Если false, запланированный Timeout между итерациями не удерживает цикл событий Node.js активным. По умолчанию: true.
  • signal <AbortSignal> Необязательный AbortSignal для отмены запланированного Timeout между операциями.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import {
  setInterval,
} from 'node:timers/promises';

const interval = 100;
for await (const startTime of setInterval(interval, Date.now())) {
  const now = Date.now();
  console.log(now);
  if ((now - startTime) > 1000)
    break;
}
console.log(Date.now());
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const {
  setInterval,
} = require('node:timers/promises');
const interval = 100;

(async function() {
  for await (const startTime of setInterval(interval, Date.now())) {
    const now = Date.now();
    console.log(now);
    if ((now - startTime) > 1000)
      break;
  }
  console.log(Date.now());
})();

timersPromises.scheduler.wait(delay[, options])

Стабильность: 1 – Экспериментальная

Эта возможность изменяется и может быть изменена или удалена в последующих версиях.

  • delay <number> Задержка в миллисекундах перед разрешением промиса.
  • options <Object>
  • ref <boolean> Если false, запланированный Timeout не удерживает цикл событий Node.js активным. По умолчанию: true.
  • signal <AbortSignal> Необязательный AbortSignal для отмены ожидания.
  • Возвращает: <Promise>

Экспериментальный API из черновика спецификации Scheduling APIs, разрабатываемой как стандарт веб-платформы.

Вызов timersPromises.scheduler.wait(delay, options) эквивалентен вызову timersPromises.setTimeout(delay, undefined, options).

1
2
3
import { scheduler } from 'node:timers/promises';

await scheduler.wait(1000); // Wait one second before continuing

timersPromises.scheduler.yield()

Стабильность: 1 – Экспериментальная

Эта возможность изменяется и может быть изменена или удалена в последующих версиях.

Экспериментальный API из черновика спецификации Scheduling APIs, разрабатываемой как стандарт веб-платформы.

Вызов timersPromises.scheduler.yield() эквивалентен вызову timersPromises.setImmediate() без аргументов.

Комментарии