Изучаем таймеры JavaScript
setTimeout()
При написании кода JavaScript может возникнуть необходимость отложить выполнение функции.
Для этого предназначен setTimeout
. Вы указываете функцию обратного вызова, которая будет выполнена позже, и значение, указывающее, насколько позже она должна быть запущена, в миллисекундах:
setTimeout(() => {
// выполняется через 2 секунды
}, 2000)
setTimeout(() => {
// выполняется через 50 миллисекунд
}, 50)
Этот синтаксис определяет новую функцию. Вы можете вызывать там любую другую функцию, или можете передать имя существующей функции и набор параметров:
const myFunction = (firstParam, secondParam) => {
// сделать что-то
}
// выполняется через 2 секунды
setTimeout(myFunction, 2000, firstParam, secondParam)
setTimeout
возвращает идентификатор таймера. Обычно он не используется, но вы можете сохранить этот идентификатор и очистить его, если хотите удалить запланированное выполнение этой функции:
const id = setTimeout(() => {
// должно выполниться через 2 секунды
}, 2000)
// передумал
clearTimeout(id)
Нулевая задержка
Если вы указываете задержку таймера равную 0, функция обратного вызова будет выполнена как можно скорее, но после завершения выполнения текущей функции:
setTimeout(() => {
console.log('после ')
}, 0)
console.log(' до ')
Этот код выведет
до
после
Это особенно полезно для того, чтобы избежать блокировки ЦП при выполнении ресурсоемких задач и позволить другим функциям выполняться во время выполнения сложных вычислений, путем помещения функций в очередь планировщика.
TIP
Некоторые браузеры (IE и Edge) реализуют метод setImmediate()
, который выполняет ту же самую функциональность, но он не является стандартным и недоступен в других браузерах. Но это стандартная функция в Node.js.
setInterval()
setInterval
— это функция, аналогичная setTimeout
, с одним отличием: вместо однократного выполнения функции обратного вызова она будет выполнять ее бесконечно, через указанный вами интервал времени (в миллисекундах):
setInterval(() => {
// выполняется каждые 2 секунды
}, 2000)
Функция выше выполняется каждые 2 секунды, пока вы не укажете ей остановиться, используя clearInterval
, передавая ей идентификатор интервала, возвращаемый setInterval
:
const id = setInterval(() => {
// выполняется каждые 2 секунды
}, 2000)
// передумал
clearInterval(id)
Обычно clearInterval
вызывается внутри функции обратного вызова setInterval
, чтобы позволить ей автоматически определить, следует ли ей выполняться снова или остановиться. Например, этот код выполняет что-то, пока App.somethingIWait не получит значение arrived:
Рекурсивный setTimeout
setInterval
запускает функцию каждые n миллисекунд, не учитывая, когда функция завершила своё выполнение.
Если функция всегда занимает одинаковое время, всё в порядке.
Возможно, функция занимает разное время выполнения в зависимости от сетевых условий.
И, возможно, одно длительное выполнение перекрывает следующее.
Чтобы избежать этого, можно запланировать рекурсивный setTimeout, который будет вызываться по завершении функции обратного вызова:
const myFunction = () => {
// выполнить что-либо
setTimeout(myFunction, 1000)
}
setTimeout(myFunction, 1000)
setTimeout
и setInterval
доступны в Node.js через модуль Timers.
Node.js также предоставляет setImmediate()
, который эквивалентен использованию setTimeout(() => {}, 0)
, в основном используется для работы с циклом событий Node.js.