Содержание

setTimeout() — JavaScript — Дока

  1. Кратко
  2. Как пишется
  3. Как понять
  4. На практике
    1. Егор Огарков советует

Кратко

Скопировано

setTimeout() позволяет исполнить функцию через указанный промежуток времени. Функция возвращает числовой идентификатор установленного таймера. Этот идентификатор можно передать в функцию clearTimeout(), чтобы остановить таймер.

Как пишется

Скопировано

const timerId = setTimeout(() => {  console.log('Прошла 1 секунда')}, 1000)console.log(timerId)// Выведет число
          const timerId = setTimeout(() => {
  console.log('Прошла 1 секунда')
}, 1000)
console.log(timerId)
// Выведет число

Пример выше установит таймер в 1 секунду и по истечении этого времени сработает функция, которая выведет в консоль сообщение.

setTimeout() принимает два аргумента:

  • функция, которая выполнится, когда таймер закончится;
  • время таймера в миллисекундах.

Миллисекунда – это одна тысячная доля секунды, то есть одна секунда состоит из 1000 миллисекунд.

В результате вызова setTimeout() вернёт идентификатор установленного таймера.

Есть вариант вызова set

Timeout() с произвольным количеством аргументов. Тогда все аргументы после второго будут передаваться в выполняемую функцию:

setTimeout(function(greeting) {  console.log(`Через секунду напечатаю «${greeting}»`)}, 1000, 'Привет')
          setTimeout(function(greeting) {
  console.log(`Через секунду напечатаю «${greeting}»`)
}, 1000, 'Привет')

Этот вариант вызова используется редко.

Как понять

Скопировано

В JavaScript код выполняется по порядку сверху вниз. Если интерпретатор встречает вызов функции, то он сразу выполняет её. Но разработчику часто может понадобиться запланировать вызов функции, чтобы она выполнилась не сразу.

Запланировать одноразовое выполнение функции можно как раз с помощью setTimeout(). Это самый простой способ исполнить функцию асинхронно.

Время таймера не гарантирует, что функция будет выполнена точно в момент, когда таймер закончится. Таймер ждёт, пока выполнится синхронный код и только потом запускает отложенную функцию, если время истекло. Строго говоря, когда мы устанавливаем таймаут, то нужно ожидать, что функция выполнится в произвольный момент после указанного времени.

Открыть демо в новой вкладке

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

Таймауты часто применяются для выпадающих списков или тултипов, чтобы закрывать их с небольшой задержкой. Только с помощью таймаутов можно создать такую полезную функцию как debounce().

На практике

Скопировано

Егор Огарков советует

Скопировано

🛠 Функция переданная в setTimeout() всегда будет вызвана только после выполнения синхронного кода, даже если выставить таймер в 0

. Дело в том, что такая функция сразу попадает в асинхронную очередь вне зависимости от значения таймера.

setTimeout(() => {  console.log('Я первый!')}, 0)// таймер равен 0console.log('Я второй!')
          setTimeout(() => {
  console.log('Я первый!')
}, 0)
// таймер равен 0
console.log('Я второй!')

В консоль сообщения выведется в следующем порядке:

  • ‘Я второй!’
  • ‘Я первый!’

🛠 Время таймера нельзя изменить динамически

// Изначально 1 секундаlet time = 1000setTimeout(() => {  console. log('Я сработал')}, time)// Поставили время 2 секундыtime = 2000
          
// Изначально 1 секунда let time = 1000 setTimeout(() => { console.log('Я сработал') }, time) // Поставили время 2 секунды time = 2000

Функция всё равно вызовется через секунду. Если возникла необходимость изменить время, то придётся сначала очистить предыдущий таймер и установить новый.

Если вы нашли ошибку, отправьте нам пул-реквест!

Во время отправки формы что-то пошло не так. Попробуйте ещё раз?

queueMicrotask()

alt +

clearTimeout()

alt +

Таймеры ⚡️ Node.js с примерами кода

В Node.js таймерами называются те функции, которые выполняют переданные им функции в какой-то момент времени в будущем и являются частью встроенного модуля Timers. Для эмуляции JavaScript API, функции модуля доступны глобально, поэтому импорт Timers не требуется.

Хотя реализация таймеров в Node.js и близка к тем, что имеются в браузере, но некоторые различия все же имеются. Рассмотрим подробно.

setTimeout()

Функция setTimeout()

выполняет переданную функцию после истечения заданного в миллисекундах интервала времени.

console.log('Console before timeout')
setTimeout(() => console.log('Delayed execution'), 3000)
console.log('Console after timeout')

Результат работы кода.

Console before timeout
Console after timeout
Delayed execution //по истечении 3 секунд

При объяснении event loop уже объяснялось, что таймеры могут выполняться не через точно заданный промежуток времени — все зависит от очереди callback-функций завершенных асинхронных операций. Если время истечет в процессе выполнения callback-ов, то таймер выполнится сразу после их завершения, но после стадии check цикла событий.

А это значит, что может пройти больше времени, чем было задано.

setImmediate()

Функция-таймер выполняет переданную ей функцию в самом конце текущей итерации event loop. Это означает, что функция выполнится после всех событий ввода/вывода.

console.log('Console before immediate')
setImmediate(() => console.log('Immediate execution'))
console.log('Console after immediate')

Результат работы кода.

Console before immediate
Console after immediate
Immediate execution //сразу после выполнения остального кода

setInterval()

Функция setInterval() используется для выполнения определенного кода множество через заданный интервал времени и принимает два параметра

  • функция для выполнения;
  • интервал времени в миллисекундах, через который переданная первым аргументом функция, должна быть вызвана снова.
setInterval(() => console.log('Interval execution'), 1000)

Результат работы кода.

Interval execution
Interval execution
Interval execution
Interval execution
... (каждую секунду)

Как и в случае с Node.js таймером setTimeout(), повторное выполнение функции не может быть гарантировано по истечении точно заданного интервала. Event loop может внести свои корректировки.

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

Каждая из Node.js функций-таймеров — setTimeout(), setImmediate() и setInterval() — при вызове возвращает объект timer, который можно использовать для завершения работы таймеров, передав его соответствующей очищающей функции.

console.log('Before')
let timeout = setTimeout(
  () => console.log('Delayed execution'),
  3000
)
let immediate = setImmediate(() =>
  console.log('Immediate execution')
)
let interval = setInterval(
  () => console.log('Interval execution'),
  1000
)
clearTimeout(timeout)
clearImmediate(immediate)
clearInterval(interval)
console.log('After')

Результат работы кода.

Before
After

Не забывайте отменять выполнение таймеров, когда они вам не нужны. Их хранение в оперативной памяти требует лишних ресурсов и может привести к утечке памяти.

Откройте для себя таймеры JavaScript

При написании кода JavaScript может потребоваться отложить выполнение функции. Узнайте, как использовать SetTimeout и SetInterval для планирования функций в будущем

Авторы статьи

СОДЕРЖА setTimeout

setTimeout()

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

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

 

JS

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

 

JS

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

 

JS

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

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

 

JS

Этот код напечатает

 

BASH

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

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

setInterval()

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

 

JS

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

 

JS

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

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

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

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

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

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

 

JS

для достижения этого сценария:

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

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

JavaScript 101: Все о таймерах

Таймеры могут быть мощными инструментами, если вы знаете, как их использовать

Таймеры JavaScript — отличные инструменты для достижения повторяющегося поведения или даже запуска отложенных действий.

Какая бы логика, основанная на времени, у вас не была, таймеры — это ответ на ваши вопросы.

Но если вы не до конца понимаете, как они работают, вы будете биться головой о стену, созданную JavaScript.

Давайте посмотрим, какие таймеры у нас есть и как они работают.

Прежде чем мы углубимся в мельчайшие детали таймеров, следует помнить о паре очень важных вещей.

Они не совсем точны

Таймеры либо запускают действие через определенное количество секунд, либо повторяют действие каждый раз, когда истекает указанный тайм-аут.

Но хотя вы можете ожидать, что они точны до секунды, реальность такова, что это не так.

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

Это проблема только в том случае, если ваша логика зависит от точных измерений времени, например, если часы отсчитывают секунды с обратным вызовом setInterval .

Пока мы помним об этом, мы можем безопасно использовать таймеры.

Это асинхронные функции

Это означает, что они не остановят выполнение программы, пока не закончат. Даже если вы укажете 0 в качестве значения времени ожидания, их поведение все равно будет асинхронным.

Это означает, что эти функции добавят ссылку на функцию, которую вы хотите вызвать, в цикл событий, поэтому, даже если вы укажете 0 для значения времени ожидания, ссылка будет поставлена ​​в очередь после всего, что будет дальше.

Функция setTimeout , вероятно, самая простая для понимания, поскольку ее основная цель — запустить функцию через несколько секунд.

Эта функция получает:

  • Ссылку на функцию для выполнения. Это код, который сработает, когда время истечет.
  • Количество секунд до выполнения функции.
  • Затем все остальные параметры передаются исполняемой функции в том же порядке.

Таким образом, следующий код напечатает «Hello World» через 3 секунды:

Это работает, потому что функция console.log объединяет все полученные параметры и выводит строку.

Но что произойдет, если вместо этого у вас будет что-то вроде этого:

Строка 14 будет работать, а строка 16 — нет. Это связано с изменением контекста выполнения вызываемой функции . На самом деле, он изменяется на глобальную область видимости. В Node это будет global , в браузере h это будет window .

В обоих случаях функция this изменяется, поэтому при выполнении строки 16 ссылка this.c больше не существует.

Итак, чтобы решить эту проблему, вы можете просто создать функцию-оболочку следующим образом:

Обратите внимание на анонимную функцию-оболочку, которую я добавил в строке 16, теперь, когда анонимная функция вызывается с двумя параметрами. Внутри него мы напрямую вызываем c.log с помощью метода call (это метод, который есть у каждой функции). Мы используем метод call , потому что мы передаем аргументы, полученные анонимной функцией, непосредственно в метод log . Мы не можем сделать это без использования , звоните , потому что мы используем динамический подход.

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

Результат этого кода следующий:

Обратите внимание, что строки 3 и 9 выполняются последними, даже если строка 9имеет тайм-аут 0.

Еще одна вещь!

Прежде чем мы оставим setTimeout в покое, что произойдет, если вы установите значение времени ожидания, а затем поймете, что должны его остановить? Вы можете убить таймер до того, как он будет выполнен, если сохраните возвращаемое значение (идентификатор таймера).

Затем это значение можно использовать с функцией clearTimeout для остановки таймера до того, как истечет время ожидания.

Давайте отредактируем прежний код, но вместо этого теперь я уберу первый тайм-аут:

В приведенном выше коде мы убиваем первый таймер до того, как он выполнит код, поэтому строка Third! (1) не будет распечатан.

Что произойдет, если вместо того, чтобы убить его, вам нужно, чтобы он повторялся каждые несколько секунд? Вот где setTimeout терпит неудачу, и мы можем использовать его брата: setInternval

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

Сигнатура этой функции точно такая же, как у функции setInterval , и объяснение всех параметров такое же.

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

Приведенный выше код запускает цикл, который срабатывает каждую секунду, и когда он срабатывает, будет выбрано случайное имя и напечатана строка «Hello ».

Не только это, но мы также устанавливаем тайм-аут в 4 секунды, который завершит бесконечный цикл, вызвав функцию clearTimeout . Конечно, у вас также есть функция clearInterval , но поскольку они работают с одним и тем же набором таймеров, вы можете использовать их взаимозаменяемо.

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

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

У вас есть еще вопросы о таймерах в JavaScript? Оставляйте их в комментариях, и я постараюсь на них ответить!

Bit Инструмент с открытым исходным кодом помогает более чем 250 000 разработчиков создавать приложения с помощью компонентов.

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

Подробнее

Разделите приложения на компоненты, чтобы упростить разработку приложений и получить наилучшие впечатления от рабочих процессов:

Как мы создаем микроинтерфейсы

масштабировать наш процесс веб-разработки.

blog.bitsrc.io

Как мы создаем систему проектирования компонентов

Создание системы дизайна с компонентами для стандартизации и масштабирования нашего процесса разработки пользовательского интерфейса.

blog.bitsrc.io

Как повторно использовать компоненты React в ваших проектах

Наконец, вы выполнили задачу по созданию фантастического поля ввода для информационного бюллетеня в вашем приложении. Вы довольны…

bit.