Пример использования setInterval. Java Script


Содержание

Scheduling: setTimeout and setInterval

We may decide to execute a function not right now, but at a certain time later. That’s called “scheduling a call”.

There are two methods for it:

  • setTimeout allows us to run a function once after the interval of time.
  • setInterval allows us to run a function repeatedly, starting after the interval of time, then repeating continuously at that interval.

These methods are not a part of JavaScript specification. But most environments have the internal scheduler and provide these methods. In particular, they are supported in all browsers and Node.js.

setTimeout

func|code Function or a string of code to execute. Usually, that’s a function. For historical reasons, a string of code can be passed, but that’s not recommended. delay The delay before run, in milliseconds (1000 ms = 1 second), by default 0. arg1 , arg2 … Arguments for the function (not supported in IE9-)

For instance, this code calls sayHi() after one second:

If the first argument is a string, then JavaScript creates a function from it.

So, this will also work:

But using strings is not recommended, use arrow functions instead of them, like this:

Novice developers sometimes make a mistake by adding brackets () after the function:

That doesn’t work, because setTimeout expects a reference to a function. And here sayHi() runs the function, and the result of its execution is passed to setTimeout . In our case the result of sayHi() is undefined (the function returns nothing), so nothing is scheduled.

Canceling with clearTimeout

A call to setTimeout returns a “timer identifier” timerId that we can use to cancel the execution.

The syntax to cancel:

In the code below, we schedule the function and then cancel it (changed our mind). As a result, nothing happens:

As we can see from alert output, in a browser the timer identifier is a number. In other environments, this can be something else. For instance, Node.js returns a timer object with additional methods.

Again, there is no universal specification for these methods, so that’s fine.

For browsers, timers are described in the timers section of HTML5 standard.

setInterval

The setInterval method has the same syntax as setTimeout :

All arguments have the same meaning. But unlike setTimeout it runs the function not only once, but regularly after the given interval of time.

To stop further calls, we should call clearInterval(timerId) .

The following example will show the message every 2 seconds. After 5 seconds, the output is stopped:

In most browsers, including Chrome and Firefox the internal timer continues “ticking” while showing alert/confirm/prompt .

So if you run the code above and don’t dismiss the alert window for some time, then in the next alert will be shown immediately as you do it. The actual interval between alerts will be shorter than 2 seconds.

Nested setTimeout

There are two ways of running something regularly.

One is setInterval . The other one is a nested setTimeout , like this:

The setTimeout above schedules the next call right at the end of the current one (*) .

The nested setTimeout is a more flexible method than setInterval . This way the next call may be scheduled differently, depending on the results of the current one.

For instance, we need to write a service that sends a request to the server every 5 seconds asking for data, but in case the server is overloaded, it should increase the interval to 10, 20, 40 seconds…

Here’s the pseudocode:

And if the functions that we’re scheduling are CPU-hungry, then we can measure the time taken by the execution and plan the next call sooner or later.

Nested setTimeout allows to set the delay between the executions more precisely than setInterval .

Let’s compare two code fragments. The first one uses setInterval :

The second one uses nested setTimeout :

For setInterval the internal scheduler will run func(i++) every 100ms:

The real delay between func calls for setInterval is less than in the code!

That’s normal, because the time taken by func ‘s execution “consumes” a part of the interval.

It is possible that func ‘s execution turns out to be longer than we expected and takes more than 100ms.

In this case the engine waits for func to complete, then checks the scheduler and if the time is up, runs it again immediately.

In the edge case, if the function always executes longer than delay ms, then the calls will happen without a pause at all.

And here is the picture for the nested setTimeout :

The nested setTimeout guarantees the fixed delay (here 100ms).

That’s because a new call is planned at the end of the previous one.

When a function is passed in setInterval/setTimeout , an internal reference is created to it and saved in the scheduler. It prevents the function from being garbage collected, even if there are no other references to it.

For setInterval the function stays in memory until clearInterval is called.

There’s a side-effect. A function references the outer lexical environment, so, while it lives, outer variables live too. They may take much more memory than the function itself. So when we don’t need the scheduled function anymore, it’s better to cancel it, even if it’s very small.

Zero delay setTimeout

There’s a special use case: setTimeout(func, 0) , or just setTimeout(func) .

This schedules the execution of func as soon as possible. But the scheduler will invoke it only after the currently executing script is complete.

So the function is scheduled to run “right after” the current script.

For instance, this outputs “Hello”, then immediately “World”:

The first line “puts the call into calendar after 0ms”. But the scheduler will only “check the calendar” after the current script is complete, so «Hello» is first, and «World» – after it.

There are also advanced browser-related use cases of zero-delay timeout, that we’ll discuss in the chapter Event loop: microtasks and macrotasks.

In the browser, there’s a limitation of how often nested timers can run. The HTML5 standard says: “after five nested timers, the interval is forced to be at least 4 milliseconds.”.

Let’s demonstrate what it means with the example below. The setTimeout call in it re-schedules itself with zero delay. Each call remembers the real time from the previous one in the times array. What do the real delays look like? Let’s see:

First timers run immediately (just as written in the spec), and then we see 9, 15, 20, 24. . The 4+ ms obligatory delay between invocations comes into play.

The similar thing happens if we use setInterval instead of setTimeout : setInterval(f) runs f few times with zero-delay, and afterwards with 4+ ms delay.

That limitation comes from ancient times and many scripts rely on it, so it exists for historical reasons.

For server-side JavaScript, that limitation does not exist, and there exist other ways to schedule an immediate asynchronous job, like setImmediate for Node.js. So this note is browser-specific.

Summary

  • Methods setTimeout(func, delay, . args) and setInterval(func, delay, . args) allow us to run the func once/regularly after delay milliseconds.
  • To cancel the execution, we should call clearTimeout/clearInterval with the value returned by setTimeout/setInterval .
  • Nested setTimeout calls are a more flexible alternative to setInterval , allowing us to set the time between executions more precisely.
  • Zero delay scheduling with setTimeout(func, 0) (the same as setTimeout(func) ) is used to schedule the call “as soon as possible, but after the current script is complete”.
  • The browser limits the minimal delay for five or more nested call of setTimeout or for setInterval (after 5th call) to 4ms. That’s for historical reasons.

Please note that all scheduling methods do not guarantee the exact delay.

For example, the in-browser timer may slow down for a lot of reasons:

  • The CPU is overloaded.
  • The browser tab is in the background mode.
  • The laptop is on battery.

All that may increase the minimal timer resolution (the minimal delay) to 300ms or even 1000ms depending on the browser and OS-level performance settings.

Tasks

Output every second

Write a function printNumbers(from, to) that outputs a number every second, starting from from and ending with to .

Make two variants of the solution.

  1. Using setInterval .
  2. Using nested setTimeout .

solution

Примеры jQuery-функции setTimeout()

JavaScript timeout представляет собой нативную javascript-функцию , которая исполняет фрагмент кода после установленной временной задержки ( в миллисекундах ). Это может пригодиться, когда нужно вывести всплывающее окошко после того, как пользователь провел некоторое время на вашей странице. Или нужно, чтобы эффект при наведении курсора на элемент запускался лишь спустя какое-то время. Таким образом, можно избежать непреднамеренного запуска эффекта, если пользователь навел курсор случайно.

Простой пример setTimeout

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

Синтаксис

В документации MDN приведен следующий синтаксис для setTimeout :

  • timeoutID – числовой id , который можно использовать в сочетании с clearTimeout() для отключения таймера;
  • func – функция, которая должна быть выполнена;
  • code ( в альтернативном синтаксисе ) – строка кода, которую нужно исполнить;
  • delay – длительность задержки в миллисекундах, после которой будет запущена функция. По умолчанию установлено значение 0.

setTimeout vs window.setTimeout

В приведенном выше синтаксисе используется window.setTimeout . Почему?

На самом деле, setTimeout и window.setTimeout – это практически одна и та же функция. Единственная разница заключается в том, что во втором выражении мы используем метод setTimeout как свойство глобального объекта window .

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

В данном руководстве я не хочу связываться с объектом window , но в целом, вы сами решаете, какой синтаксис стоит использовать.

Примеры использования

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

Это может быть название функции:

Переменная, которая обращается к функции:

Или же анонимная функция:

Но я не рекомендую так делать по следующим причинам:

  • Такой код плохо воспринимается, а, следовательно, его сложно будет модернизировать или отладить;
  • Он предполагает использование метода eval() , который может стать потенциальной уязвимостью;
  • Этот метод работает медленнее других, так как ему требуется запускать JavaScript-интерпретатор .

Также обратите внимание, что для тестирования кода мы используем метод alert для JavaScript timeout .

Передаем параметры в setTimout

В первом ( к тому же, кроссбраузерном ) варианте мы передаем параметры в callback-функцию , исполняемую при помощи setTimeout .

В следующем примере мы выделяем случайное приветствие из массива greetings и передаем его в качестве параметра функции greet() , которая исполняется setTimeout с задержкой в 1 секунду:

Альтернативный метод

В синтаксисе, приведенном в начале статьи, существует еще один метод, с помощью которого можно передать параметры в callback-функцию , исполняемую JavaScript timeout . Данный метод подразумевает под собой вывод всех параметров, следующих после задержки.

Опираясь на предыдущий пример, мы получаем:

Этот метод не будет работать в IE 9 и ниже, где передаваемые параметры расцениваются как undefined . Но для решения этой проблемы на MDN есть специальный полифилл .

Сопутствующие проблемы и “this”

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

Причина такого вывода кроется в том, что в первом примере this ведет к объекту person , а во втором примере — указывает на глобальный объект window , у которого отсутствует свойство firstName .

Чтобы избавиться от этой нестыковки, можно воспользоваться несколькими методами:

Принудительно установить значение this

Это можно сделать при помощи bind() – метода, который создает новую функцию, которая при вызове в качестве значения ключа this использует определенное значение. В нашем случае — указанный объект person . Это в результате дает нам:

Примечание: метод bind был представлен в ECMAScript 5 , а значит, что он будет работать только в современных браузерах. В других при его применении вы получите ошибку выполнения JavaScript « function timeout error » .

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

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

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

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

Давайте посмотрим на нее в действии. В следующем примере, если кликнуть по кнопке « Start countdown », начнется обратный отсчет. После того, как он завершится, котята получат свое. Но если нажать кнопку « Stop countdown », таймер JavaScript timeout будет остановлен и сброшен.

Подведем итоги

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

Многие также путают использование JavaScript-функции setTimeout , и jQuery-метода delay . Метод delay предназначен для установки временной задержки между методами в заданной очереди jQuery . Задержку отметить невозможно.

К примеру, если вы хотите затемнить изображение на секунду, сделать его видимым на 5 секунд, а затем снова затемнить на 1 секунду, то придется сделать следующее:

Все же лучше использовать JavaScript timeout для чего-то другого.

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

В завершение

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

Данная публикация представляет собой перевод статьи « jQuery setTimeout() Function Examples » , подготовленной дружной командой проекта Интернет-технологии.ру

setInterval вызов одной функции с разными параметрами

Подскажите, пожалуйста, как нужно каждые 5 секунд вызывать одну функцию с разными параметрами.

Javascript
29.05.2012, 13:23

Как работает циклический вызов setInterval?
Все доброго дня. Подскажите как работает циклический вызов setInterval? Меня интересует момент.

Конструктор с разными параметрами
. извините что обращаюсь, сам не местный. ))) пробую создать обьект и написать конструктор.

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

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


29.05.2012, 14:16 2
Javascript
29.05.2012, 15:08 [ТС] 3
29.05.2012, 15:18 4

Чётче формулируйте задачу. Если надо непрерывно, то так:

Javascript
29.05.2012, 15:18
29.05.2012, 15:27 [ТС] 5

Спасибо большое, подумал и разобрался.

Вынес в отдельную функцию

и запустил через setInterval

Добавлено через 8 минут
GuardCat, и еще пару, как дела обстоят с памятью — если отставить на сутки — браузер не заглючит?

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

Javascript
29.05.2012, 15:39 6
29.05.2012, 16:26 7

Леха, если браузер сутки показывает, скажем gmail, то памяти он так и так сожрёт вагон. Периодически закрывать его нужно.

Javascript
29.05.2012, 16:41 8

Свойство у объекта — оно ОДНО.
Например window.name — присвоили какое-то значение — оно ОДНО и будет, покуда не измените.

А setTimeout — это метод.
Всякое исполнение этого метода порождает внутренний объект окна Timeout, к свойствам которого нет программного доступа.
Единственное, что нам доступно — это идентификатор этого внутреннего объекта и возможность через этот идентификатор один конкретный внутренний объект из открытых очистить (закрыть) — методом clearTimeout ().

Литературы по этому делу — вагон и тележка. Поищите сами.

29.05.2012, 17:21 9

После остановки, начнёт с того места, на котором остановилась.

kalabuni, garbageCollector уничтожает служебный объект после вызова первого аргумента setTimeout. С иной информацией в литературе я не сталкивался.

Интервал времени в Javascript — Методы setTimeout, setInterval и clearInterval объекта Window

Урок №1 Интервал времени — setInterval и clearInterval

Количество просмотров : 1248

Здесь будут рассмотрены методы setTimeout , setInterval и clearInterval объекта Window, которые предназначены для отсроченного выполнения какого-либо кода.

В javascript нередко используется интервал времени для задержки исполнении кода.

Метод setTimeout — Однократное выполнение кода через интервал времени

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

Интервал времени указывается в миллисекундах .

setTimeout ( код , время )

Как Вы наглядно смогли убедиться, метод setTimeout вернул выполнение кода через указанный промежуток времени — 3000 миллиСекунд (это 3 секунды).

Но удобнее javascript -код поместить в функцию, которую затем указать в качестве первого параметра метода setTimeout .

Результат тот же, что и в предыдущем примере.

Метод setInterval — Многократное выполнение кода через интервал времени

Метод setInterval предназначен для многократного выполнения кода через указанный интервал времени.

Метод setInterval возвращает идентификатор , по которому можно отменить выполнение кода (об этом далее. ).

Как видно из примера — одно и то же действие (всплывающее окно) повторяется через интервал в 7 секунд. И так до бесконечности .

Метод clearInterval — Прерывает запланированное выполнение кода

С помощью метода clearInterval можно прервать запланированное методом setInterval выполнение кода .

Для этого воспользуемся идентификатором, возвращаемым методом setInterval (идентификатор помещают в произвольную переменную).

Итак, еще раз повторим, что мы делаем в этом примере:

  • Метод setInterval возвращает идентификатор, который мы помещаем в произвольную переменную idInt .
  • Переменную idInt используем в любом месте программы в качестве параметра метода clearInterval для прерывания многократного действия, совершаемого методом setInterval .

Домашнее задание — Методы setInterval и clearInterval

Использование интервалов в javascript . Решаем самостоятельно задачу по этой теме.

Для решения задания нужно работать с методами setInterval и clearInterval .

1-я часть задачи :

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

«Прошло: 2 сек.» // И так далее

2-я часть задачи :

Допишите программу так, чтобы она останавливалась при достижении 5 секунд и надпись о пройденном времени больше не выводилась в консоль.

Почему не работает setInterval даже на самом простом примере?

Решил воспользоваться цикличным повторением кода на JQuery. Для этого взял функцию setInterval, которая по своей логике должна повторять переданный ей код или функцию через указанное количество времени. Вот что я написал для примера:
var interv = setInterval(alert(«1»),4000);
Этот код не заработал как надо. Он выполняется ОДИН раз. Больше не запускается. Я даже через инструментарий разработчика проверил, событие не запускается. Даже через console.log вёл лог запуска, этот код запустился единожды и потух. Я даже из JS файла весь остальной код убрал, оставил так:

И так не работает! Даже в разных браузерах проверил. Что я не так делаю?

Управляемый цикл в javascript

При разработке фронтэнда, особенно слайдеров на js, часто требуется использовать циклы, потому что, например, слайды должны автоматически переключаться сами через определённый интервал времени. Для организации циклов на javascript используется функция setInterval. Но на таких слайдерах часто нужно организовать и ручное переключение слайдов, таким образом, в момент ручного включения определённого слайда, цикл должен прерваться. Программист в этом случае может столкнуться с такой задачей, как прерывание цикла setInterval.

Пример использования управляемого цикла в javascript с помощью функций setInterval и clearInterval

Функция которая будет выполняться повторяться в цикле:

Устанавливаем паузу между иттерациями цикла в милисекундах

Запускаем цикл (функция setInterval) и назначаем ему идентификатор «intervalID»

Что-бы прервать выполнение скрипта используем функцию clearInterval

JavaScript метод WindowOrWorkerGlobalScope.setInterval()

Определение и применение

JavaScript метод setInterval() объекта WindowOrWorkerGlobalScope многократно вызывает функцию или выполняет фрагмент кода с фиксированной задержкой времени между каждым вызовом.

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

Метод setInterval() возвращает положительное числовое целое ненулевое значение, которое определяет таймер, это значение может быть передано методу clearInterval(), чтобы отменить выполнение программного кода, ранее отложенного вызовом метода setInterval().


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

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

Поддержка браузерами

Javascript
Метод Chrome Firefox Opera Safari IExplorer Edge
setInterval() Да Да Да Да Да Да

JavaScript синтаксис:

Cпецификация

Значения параметров

Параметр Описание
function Функция, которая будет многократно выполняться после истечения таймера.
delay Время в миллисекундах, которое таймер должен ждать перед выполнением указанной функции или кода. Если этот параметр опущен, то используется значение 0, оно означает, что выполнение должно произойти немедленно, или, точнее, как можно скорее (как только завершат работу все обработчики событий). Если этот параметр меньше 4, то используется значение 4. Обратите внимание, что в любом случае фактическая задержка может быть больше, чем предполагалось, причины задержек перечислены ниже в примерах.
param1, . paramX Дополнительные параметры, передаваемые функции, указанной функцией или кодом, по истечении таймера. Передача дополнительных параметров функции в первом синтаксисе не работает в Internet Explorer 9 и ниже. Если вы хотите включить эту функцию в этом браузере, необходимо использовать полифилл.
code Альтернативный синтаксис, который позволяет включать строку вместо функции, которая компилируется и выполняется по истечении таймера. Этот синтаксис не рекомендован к использованию в связи с угрозой безопасности.

Пример использования

Базовое использование

В этом примере с использованием атрибута событий onclick при нажатии на первую кнопку (HTML элемент ) вызываем функцию runCounter(), которая с использованием JavaScript метода setInterval() задает таймер, который многократно выполняет функцию showCounter() каждые 1000 миллисекунд (1 секундa).

Функция showCounter() в свою очередь инкрементирует (увеличивает на 1) значение переменной counter, с помощью метода getElementById() находит элемент с определенным глобальным атрибутом id и изменяет его содержимое значением переменной counter.

С использованием атрибута событий onclick при нажатии на вторую кнопку (HTML элемент ) вызываем функцию clearMyTimeOut(), которая с использованием JavaScript метода clearInterval() отменяет повторяющееся выполнение программного кода, которое было ранее установлено вызовом метода setInterval(), устанавливает значение переменной counter равное нулю и добавляет элементу это содержимое.

Результат нашего примера:

Пример использования методов setInterval() и clearInterval() объекта WindowOrWorkerGlobalScope

Проблема с this

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

Код, выполняемый setInterval(), вызывается из контекста выполнения, отдельного от функции, из которой был вызван setInterval(). Обычные правила установки контекста для ключевого слова this для вызываемой функции применяются, и если вы не установили его явно в вызове или с определенной привязкой, то он по умолчанию будет глобальным (или оконным) объектом в нестрогом режиме или будет неопределенным в строгом режиме. Он не будет таким же, как this для функции, которая вызвала метод setInterval(). Значение this по умолчанию метода setInterval() по-прежнему будет объектом window , а не неопределенным, даже в строгом режиме. Давайте рассмотрим следующий пример:

Обратите внимание, что при передаче метода методу setInterval() мы получаем ошибку. Оптимальным и самым простым решением этой проблемы в данном случае будет использование анонимной функции обертки:

Передача строковых литералов

Метод setInterval() имеет альтернативный синтаксис, который позволяет включать строку вместо функции, которая компилируется и выполняется по истечении таймера:

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

Максимальная задержка выполнения

Браузеры, включая Internet Explorer, Chrome, Safari и Firefox хранят значение тайм-аута как 32-разрядное целое число со знаком внутри. Значения выше 2147483647 миллисекунд (около 24,8 дней) вызовут переполнение, в результате чего вызов переданной функции произойдет немедленно.

Причины увеличения задержек

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

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

Чтобы уменьшить нагрузку (и связанное с ней использование батареи) с фоновых вкладок, тайм-ауты регулируются до срабатывания не чаще одного раза в секунду (1000 миллисекунд) в неактивных вкладках.

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

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

Длительность выполнения меньше интервала

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

В приведенном выше фрагменте объявлена именованная функция loop(), которая немедленно выполняется, эта функция рекурсивно вызывается внутри метода setTimeout() после завершения выполнения логики. Хотя этот шаблон и не гарантирует выполнение на фиксированном интервале, но он гарантирует, что предыдущий интервал был завершен до рекурсии.

Пример использования setInterval. Java Script

setTimeout и setInterval

Почти все реализации JavaScript имеют внутренний таймер-планировщик, который позволяет задавать вызов функции через заданный период времени.

В частности, эта возможность поддерживается в браузерах и в сервере Node.JS.

func/code : Функция или строка кода для исполнения. Строка поддерживается для совместимости, использовать её не рекомендуется.

delay : Задержка в миллисекундах, 1000 миллисекунд равны 1 секунде.

arg1 , arg2 . : Аргументы, которые нужно передать функции. Не поддерживаются в IE9-.

Исполнение функции произойдёт спустя время, указанное в параметре delay .

Например, следующий код вызовет func() через одну секунду:

С передачей аргументов (не сработает в IE9-):

Если первый аргумент является строкой, то интерпретатор создаёт анонимную функцию из этой строки.

То есть такая запись тоже сработает:

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

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

Отмена исполнения clearTimeout

Функция setTimeout возвращает числовой идентификатор таймера timerId , который можно использовать для отмены действия.

В следующем примере мы ставим таймаут, а затем удаляем (передумали). В результате ничего не происходит.

Как видно из alert , в браузере идентификатор таймера является обычным числом. Другие JavaScript-окружения, например Node.JS, могут возвращать объект таймера, с дополнительными методами.

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

Таймеры — это надстройка над JavaScript, которая описана в секции Timers стандарта HTML5 для браузеров и в документации к Node.JS — для сервера.

Метод setInterval имеет синтаксис, аналогичный setTimeout .

Смысл аргументов — тот же самый. Но, в отличие от setTimeout , он запускает выполнение функции не один раз, а регулярно повторяет её через указанный интервал времени. Остановить исполнение можно вызовом clearInterval(timerId) .

Следующий пример при запуске станет выводить сообщение каждые две секунды, пока не пройдёт 5 секунд:

Важная альтернатива setInterval — рекурсивный setTimeout :

В коде выше следующее выполнение планируется сразу после окончания предыдущего.

Рекурсивный setTimeout — более гибкий метод тайминга, чем setInterval , так как время до следующего выполнения можно запланировать по-разному, в зависимости от результатов текущего.

Например, у нас есть сервис, который раз в 5 секунд опрашивает сервер на предмет новых данных. В случае, если сервер перегружен, можно увеличивать интервал опроса до 10, 20, 60 секунд. А потом вернуть обратно, когда всё нормализуется.

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

Рекурсивный setTimeout гарантирует паузу между вызовами, setInterval — нет.

Давайте сравним два кода. Первый использует setInterval :

Второй использует рекурсивный setTimeout :

При setInterval внутренний таймер будет срабатывать чётко каждые 100 мс и вызывать func(i) :

Вы обратили внимание.

Реальная пауза между вызовами func при setInterval меньше, чем указана в коде!

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

Возможно и такое что func оказалась сложнее, чем мы рассчитывали и выполнялась дольше, чем 100 мс.

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


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

Исключением является IE, в котором таймер «застывает» во время выполнения JavaScript.

А так будет выглядеть картинка с рекурсивным setTimeout :

При рекурсивном setTimeout задержка всегда фиксирована и равна 100 мс.

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

Минимальная задержка таймера

У браузерного таймера есть минимальная возможная задержка. Она меняется от примерно нуля до 4 мс в современных браузерах. В более старых она может быть больше и достигать 15 мс.

По стандарту, минимальная задержка составляет 4 мс. Так что нет разницы между setTimeout(. 1) и setTimeout(. 4) .

Посмотреть минимальное разрешение «вживую» можно на следующем примере.

В примере ниже каждая полоска удлиняется вызовом setInterval с указанной на ней задержкой — от 0 мс (сверху) до 20 мс (внизу).

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

[iframe border=»1″ src=»https://github.com/iliakan/javascript-tutorial-ru/blob/master/1-js/7-js-misc/3-settimeout-setinterval/setinterval-anim» link edit]

Реальная частота срабатывания

В ряде ситуаций таймер будет срабатывать реже, чем обычно. Задержка между вызовами setInterval(. 4) может быть не 4 мс, а 30 мс или даже 1000 мс.

Большинство браузеров (десктопных в первую очередь) продолжают выполнять setTimeout/setInterval , даже если вкладка неактивна.

При этом ряд из них (Chrome, FF, IE10) снижают минимальную частоту таймера, до 1 раза в секунду. Получается, что в «фоновой» вкладке будет срабатывать таймер, но редко.

При работе от батареи, в ноутбуке — браузеры тоже могут снижать частоту, чтобы реже выполнять код и экономить заряд батареи. Особенно этим известен IE. Снижение может достигать нескольких раз, в зависимости от настроек.

При слишком большой загрузке процессора JavaScript может не успевать обрабатывать таймеры вовремя. При этом некоторые запуски setInterval будут пропущены.

Вывод: на частоту 4 мс стоит ориентироваться, но не стоит рассчитывать.

Разбивка долгих скриптов

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

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

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

Например, осуществляется анализ и подсветка первых 100 строк, затем через 20 мс — следующие 100 строк и так далее. При этом можно подстраиваться под CPU посетителя: замерять время на анализ 100 строк и, если процессор хороший, то в следующий раз обработать 200 строк, а если плохой — то 50. В итоге подсветка будет работать с адекватной быстротой и без тормозов на любых текстах и компьютерах.

  • Методы setInterval(func, delay) и setTimeout(func, delay) позволяют запускать func регулярно/один раз через delay миллисекунд.
  • Оба метода возвращают идентификатор таймера. Его используют для остановки выполнения вызовом clearInterval/clearTimeout .
  • В случаях, когда нужно гарантировать задержку между регулярными вызовами или гибко её менять, вместо setInterval используют рекурсивный setTimeout .
  • Минимальная задержка по стандарту составляет 4 мс . Браузеры соблюдают этот стандарт, но некоторые другие среды для выполнения JS, например Node.JS, могут предоставить и меньше задержки.
  • В реальности срабатывания таймера могут быть гораздо реже, чем назначено, например если процессор перегружен, вкладка находится в фоновом режиме, ноутбук работает от батареи или по какой-то иной причине.

Браузерных особенностей почти нет, разве что вызов setInterval(. 0) с нулевой задержкой в IE недопустим, нужно указывать setInterval(. 1) .

Интервал времени в Javascript — Методы setTimeout, setInterval и clearInterval объекта Window

Урок №1 Интервал времени — setInterval и clearInterval

Количество просмотров : 1249

Здесь будут рассмотрены методы setTimeout , setInterval и clearInterval объекта Window, которые предназначены для отсроченного выполнения какого-либо кода.

В javascript нередко используется интервал времени для задержки исполнении кода.

Метод setTimeout — Однократное выполнение кода через интервал времени

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

Интервал времени указывается в миллисекундах .

setTimeout ( код , время )

Как Вы наглядно смогли убедиться, метод setTimeout вернул выполнение кода через указанный промежуток времени — 3000 миллиСекунд (это 3 секунды).

Но удобнее javascript -код поместить в функцию, которую затем указать в качестве первого параметра метода setTimeout .

Результат тот же, что и в предыдущем примере.

Метод setInterval — Многократное выполнение кода через интервал времени

Метод setInterval предназначен для многократного выполнения кода через указанный интервал времени.

Метод setInterval возвращает идентификатор , по которому можно отменить выполнение кода (об этом далее. ).

Как видно из примера — одно и то же действие (всплывающее окно) повторяется через интервал в 7 секунд. И так до бесконечности .

Метод clearInterval — Прерывает запланированное выполнение кода

С помощью метода clearInterval можно прервать запланированное методом setInterval выполнение кода .

Для этого воспользуемся идентификатором, возвращаемым методом setInterval (идентификатор помещают в произвольную переменную).

Итак, еще раз повторим, что мы делаем в этом примере:

  • Метод setInterval возвращает идентификатор, который мы помещаем в произвольную переменную idInt .
  • Переменную idInt используем в любом месте программы в качестве параметра метода clearInterval для прерывания многократного действия, совершаемого методом setInterval .

Домашнее задание — Методы setInterval и clearInterval

Использование интервалов в javascript . Решаем самостоятельно задачу по этой теме.

Для решения задания нужно работать с методами setInterval и clearInterval .

1-я часть задачи :

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

«Прошло: 2 сек.» // И так далее

2-я часть задачи :

Допишите программу так, чтобы она останавливалась при достижении 5 секунд и надпись о пройденном времени больше не выводилась в консоль.

Всё только о JavaScript

Чем плох setInterval

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

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

Вывод будет информативным, начиная со второй строчки.

В Firefox, Opera, Safari и Chrome ситуация будет схожая: первое число будет примерно равно 1000 , второе — на 200 меньше. Различие будут только в разбросе значений. Самый маленький разброс в Chrome и Opera.

1000 800
1003 803
1004 804
1018 808
987 787
1003 803
1000 800

Чуть больше разброс в Safari.

1035 835
1259 1059
841 641
1091 891
1048 848
1005 805
998 798

И самый большой — в Firefox.

988 788
985 785
1007 807
971 771
984 784
990 790
974 774
1010 810
1004 804

В Internet Explorer ситуация более стабильная, но противоположная: 1000 равно второе число, а первое на 200 больше.

1203 1000
1203 1000
1203 1000
1203 1000
1204 1000
1203 1000
1203 1000

Другими словами IE устанавливает таймер на следующий запуск после выполнения callback-функции, а остальные браузеры — до. Поэтому, например, анимация, реализованная с помощью setInterval в Internet Explorer всегда будет медленнее, чем в других браузерах.

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

И после запуска перевести системное время на минуту назад, то в браузерах Firefox и Safari смена чисел приостановится, а через минуту запустится вновь. Конечно, ручной перевод системного времени крайне редкая ситуация, но на многихсистемах настроена автоматическая синхронизация времени с серверами в интернете, поэтому в некоторых ситуациях нельзя сбрасывать со счетов этот фактор.

Ещё один маленький минус функции setInterval — чтобы была возможность остановить её действие, необходимо где-то запоминать её идентификатор, что не всегда удобно.

Чем заменить setInterval

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

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

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

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

Илон Маск рекомендует:  Помещение одного запроса внутрь другого
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL