Планирование – процесс, который может потребоваться в совершенно разных проектах. Вызов функций в приложениях возможен как сразу, так и через заданный временной интервал. Реализовывать операции «по таймеру» можно при помощи «чистого» JavaScript. Добиться желаемого результата обычно легко.

Далее предстоит научиться работать с таймерами и задержкой. Необходимо изучить функции, связанные с рассматриваемым элементом языка программирования. А еще – ознакомиться с несколькими примерами таймеров и задержки. Эта информация рассчитана на широкую публику. Она подойдет как начинающим веб-программистам, так и уже более опытным их коллегам.

Краткая характеристика

За таймеры в the JS отвечают два разных метода:

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

Соответствующие методы не являются частью спецификации the JavaScript. Несмотря на это, большинство сред выполнения the JS-кода имеют внутренний планировщик и предоставляют доступ к упомянутым функциям. Они поддерживаются во всех браузерах, а также в Node.js. Далее оба этих метода будут изучены более подробно. Акцент сделан на первом варианте – он встречается чаще.

TimeOut – это…

TimeOut – это нативная функция the JavaScript. С ее помощью можно задать задержку (таймер) в том или ином проекте. Время здесь должно указываться в миллисекундах.

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

Синтаксис

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

let timerId = setTimeout (func|code, [delay], [arg1], [arg2],…);

Здесь:

  1. Func|code – это функция или строка кода, отправляемого на выполнение. Чаще всего соответствующий элемент представляет собой именно определенную команду. Строка кода может быть передана сюда, но это – крайне редкая ситуация.
  2. Delay – параметр, указывающий на задержку перед запуском. Указывается в миллисекундах (1000 мс = 1 с). Значение по умолчанию установлено на уровне 0.
  3. Arg1, arg2, … – аргументы, передаваемые в заданную функцию.

The setTimeOut – команда, которая работает элементарно. Это таймер обратного отсчета. Далее предстоит познакомиться со всеми способами использования упомянутой команды.

Передача параметров

Если необходимо задать задержку (паузу) в программе на the JS, требуется запомнить принцип передачи параметров в используемый метод.

Таймер: особенности разработки и пример кода

Выше представлен программный код, где необходимо передать параметры в callback-функцию. Она будет работать при помощи the setTimeOut. Нужно выделить случайное приветствие из заданного массива с названием greetings. Теперь оно передается в качестве параметра функции greet. Операция осуществляется с задержкой в 1 секунду.

Альтернативное решение

Ранее представленный синтаксис подразумевает использование метода, через который допустима передача параметров в callback-функции. В этом случае выводятся все параметры, идущие после задержки.

setTimeout (greet, 1000, randomGreeting);

Выше – пример того, как это выглядит на практике. Метод не работает в IE 9 и более старых сборках соответствующего браузера. Данная особенность обусловлена тем, что передаваемые параметры выступают в качестве undefined. Проблема может быть решена – для этого разработчик должен обратиться к официальной документации. Начинающим веб-программистам соответствующая информация не нужна.

Вероятные трудности

При попытках установить в программном обеспечении один или несколько таймеров можно столкнуться с определенными трудностями. Из-за этого приходится запоминать некоторые правила и особенности разработки на the JS:

  • код, исполняемый при помощи setTimeOut, запускается отдельно от функции, для которой он был вызван;
  • некоторые трудности разработки решаются при помощи ключевого слова this.

Чтобы решать проблемы, связанные с реализацией таймеров, можно пользоваться специальной библиотекой, а также принудительной установкой this. Далее эти два подхода будут рассмотрены более подробно.

Принудительная this-установка

Чтобы команда the setTimeOut работала в исходном коде без ошибок, можно принудительно установить this. Операция доступна при помощи blind(). Это метод, позволяющий в the JavaScript вызвать новую функцию. При обращении к ней в виде значения ключа this присваивается определенный параметр.

setTimeOut (person.introduce,blind(person), 50);

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

Использование библиотек

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

setTimeOut($.proxy(person.introduce, person), 50);

Выше – образец кода, который демонстрирует использование библиотек для решения проблем, связанных с this и таймерами/задержкой.

Отмена (отключение) таймера

The JS – простой, понятный и функциональный язык программирования. Он предусматривает методы и команды, которые пригодятся при создании достаточно сложных проектов. Иногда уже установленный таймер необходимо отключить. Для этого the JS поддерживает отдельный метод (команду) – clearTimeOut.

Вызов setTimeOut возвращает идентификатор таймера (timerId), который можно использовать для отмены дальнейшей реализации. Синтаксическая форма представления кода, применяемого для данной цели имеет следующий вид:

let timerId = setTimeout(…);

clearTimeout(timerId);

А вот наглядный пример реализации этой команды:

Таймер: особенности разработки и пример кода

В браузере идентификатором таймера выступает целое число. В других средах ими могут выступать иные компоненты. Пример – Node.js. Он вернет объект таймера с дополнительными методами.

Если использовать в программном коде метод stop, он остановит таймер. Полученные результаты будут сброшены. Отсчет времени начнется с самого начала.

SetInterval – второй метод

Чтобы реализовать задержку в программном коде the JS, можно использовать еще один метод. А именно – setInterval. Его синтаксическая форма будет точно такой же, как и в случае с the setTimeOut.

Аргументы здесь предусматривают точно такое же значение. Отличие от the setTimeOut заключается в том, что команда запускается не один раз, а периодически с интервалом в указанное время.

Чтобы остановить дальнейшую реализацию команды, требуется обращение к clearInterval(timerId). Вот пример, который поможет вывести сообщение на экран с интервалом 2 секунды. Через 5 секунд эта операция будет прекращена:

Таймер: особенности разработки и пример кода

У большинства браузеров, включая the Chrome и Mozilla FireFox внутренний счетчик продолжает работать во время показа alert/confirm/prompt.

При запуске предложенного выше фрагмента кода и ожидании с закрытием alert несколько секунд, следующий alert будет показан сразу после закрытия предыдущего. Интервал времени между alert-сообщениями окажется менее 2–х секунд.

Вложенный setTimeOut

Регулярный запуск чего-либо в программном коде допускается несколькими методами. Первый – это использование the setInterval. Второй – применение так называемого вложенного setTimeOut. Вот наглядный пример реализации этой идеи:

Таймер: особенности разработки и пример кода

Метод the setTimeOut в предложенном фрагменте планирует следующий вызов прямо после окончания текущего (*). Вложенный the setTimeOut – это более гибкий метод, чем the setInterval. С его помощью допустимо задание поведения таймера в зависимости от предыдущих результатов.

Пример – нужно написать сервис, который будет отправлять запросы для получения данных на сервер с интервалом каждые 5 секунд. Если же серверная сторона перегружена, временной промежуток увеличивается до 10, 20, 40 секунд. Вот как это будет выглядеть в программном коде:

Таймер: особенности разработки и пример кода

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

Вложенный the setTimeOut дает возможность задать задержку между выполнениями команд более точно, чем the setInterval. Вот два фрагмента кода, которые объяснят разницу между упомянутыми методами. Первый использует the setInterval, а второй – the setTimeOut:

Таймер: особенности разработки и пример кода
Таймер: особенности разработки и пример кода

Для the setInterval внутренний планировщик будет выполнять func(i) с интервалом 100 мс:

Таймер: особенности разработки и пример кода

Реальная задержка между вызовами func при помощи the setInterval меньше, чем указано в программном коде. Соответствующее явление – вариант нормы. Это связано с тем, что время, затраченное на выполнение func, использует часть заданного временного интервала. Реализация func может оказаться более долгой и отнять больше 100 мс.

В описанном случае движок будет:

  1. Ждать окончания выполнения func.
  2. Проверять после реализации func планировщик.
  3. Немедленно запускать реализацию снова, если время подошло к концу.
  4. В противном случае (когда команда всегда выполняется дольше задержки delay) вызовы будут реализовываться без каких-либо задержек.

Ниже можно увидеть изображение, демонстрирующее работу рекурсивного (вложенного) the SetTimeOut:

Таймер: особенности разработки и пример кода

Вложенный метод таймера the SetTimeOut гарантирует фиксированную задержку. В рассматриваемом примере она составляет 100 мс. Такой результат достигается за счет того, что новый вызов планируется в конце предыдущего.

Сборка мусора и callback

При передаче функции в setInterval или setTimeOut, на нее создается внутренняя ссылка. Она сохраняется в имеющемся планировщике (таймере). Данный подход позволит избежать попадания команды в сборщик мусора, даже если на нее отсутствуют другие ссылки.

Таймер: особенности разработки и пример кода

Здесь для the setInterval в таймере функция останется в памяти до непосредственного обращения к clearInterval.

При работе с таймерами необходимо также помнить о так называемом «побочном эффекте». Функция ссылается на внешнее лексическое окружение. Это приводит к тому, что пока она существует, внешние переменные тоже присутствуют. Они могут отнимать больше памяти, чем сама задействованная функция. Из-за этой особенности лучше отменять регулярный вызов той или иной команды, если в нем нет необходимости. Соответствующий принцип применим не только к крупным операциям, но и к самым маленьким функциям.

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

Еще один момент, который необходимо запомнить при работе с таймерами – это особый вариант использования метода the setTimeOut. Речь идет о так называемой нулевой задержке.

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

Таймер: особенности разработки и пример кода

Первая строка в заданном таймере помещает вызов в «календарь» через 0 мс. Планировщик все равно проверит этот самый «календарь» после завершения текущего программного кода. Все это приводит к тому, что «Привет» будет выведено на экран первым, а «Мир» – вторым.

RequestAnimationFrame()

В процессе изучения таймеров рекомендуется обратить внимание на еще один метод. Речь идет о the requestAnimationFrame. Этот метод таймера работает точно так же, как и the setInterval, но за исключением области применения. Соответствующий вариант больше заточен под анимацию, а также работу с графикой.

Таймер: особенности разработки и пример кода

The requestAnimationFrame предусматривает ряд оптимизаций, позволяющих добиться лучшей производительности. В примере с таймером выше window.requestAnimationFrame() получает функцию, которая вызывается определенное количество раз (обычно – 60) в секунду. В соответствующий метод передается команда moveRect. Она используется для изменения угла поворота блока на веб-сайте. Далее предстоит снова обратиться к методу window.requestAnimationFrame(). Возвращаемым результатом станет уникальный id. Он может использоваться в будущем в таймере для остановки анимации:

Таймер: особенности разработки и пример кода

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

Хотите освоить современную IT-специальность? Огромный выбор курсов по востребованным IT-направлениям есть в Otus!