Setinterval javascript не работает

Планирование: setTimeout и setInterval

Мы можем вызвать функцию не в данный момент, а позже, через заданный интервал времени. Это называется «планирование вызова».

Для этого существуют два метода:

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

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

setTimeout

func|code Функция или строка кода для выполнения. Обычно это функция. По историческим причинам можно передать и строку кода, но это не рекомендуется. delay Задержка перед запуском в миллисекундах (1000 мс = 1 с). Значение по умолчанию – 0. arg1 , arg2 … Аргументы, передаваемые в функцию (не поддерживается в IE9-)

Например, данный код вызывает sayHi() спустя одну секунду:

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

Это также будет работать:

Но использование строк не рекомендуется. Вместо этого используйте функции. Например, так:

Начинающие разработчики иногда ошибаются, добавляя скобки () после функции:

Это не работает, потому что setTimeout ожидает ссылку на функцию. Здесь sayHi() запускает выполнение функции, и результат выполнения отправляется в setTimeout . В нашем случае результатом выполнения sayHi() является undefined (так как функция ничего не возвращает), поэтому ничего не планируется.

Отмена через clearTimeout

Вызов setTimeout возвращает «идентификатор таймера» timerId , который можно использовать для отмены дальнейшего выполнения.

Синтаксис для отмены:

В коде ниже планируем вызов функции и затем отменяем его (просто передумали). В результате ничего не происходит:

Как мы видим из вывода alert , в браузере идентификатором таймера является число. В других средах это может быть что-то ещё. Например, Node.js возвращает объект таймера с дополнительными методами.

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

Для браузеров таймеры описаны в разделе таймеров стандарта HTML5.

setInterval

Метод setInterval имеет такой же синтаксис как setTimeout :

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

Чтобы остановить дальнейшее выполнение функции, необходимо вызвать clearInterval(timerId) .

Следующий пример выводит сообщение каждые 2 секунды. Через 5 секунд вывод прекращается:

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

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

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

Есть два способа запускать что-то регулярно.

Один из них setInterval . Другим является рекурсивный setTimeout . Например:

Метод setTimeout выше планирует следующий вызов прямо после окончания текущего (*) .

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

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

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

Читайте также:  Как настроить цифровой эфирный приемник cadena cdt 100

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

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

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

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

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

Это нормально, потому что время, затраченное на выполнение func , использует часть заданного интервала времени.

Вполне возможно, что выполнение func будет дольше, чем мы ожидали, и займёт более 100 мс.

В данном случае движок ждёт окончания выполнения func и затем проверяет планировщик и, если время истекло, немедленно запускает его снова.

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

Ниже представлено изображение, показывающее процесс работы рекурсивного setTimeout :

Рекурсивный setTimeout гарантирует фиксированную задержку (здесь 100 мс).

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

Когда функция передаётся в setInterval/setTimeout , на неё создаётся внутренняя ссылка и сохраняется в планировщике. Это предотвращает попадание функции в сборщик мусора, даже если на неё нет других ссылок.

Для setInterval функция остаётся в памяти до тех пор, пока не будет вызван clearInterval .

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

setTimeout с нулевой задержкой

Особый вариант использования: setTimeout(func, 0) или просто setTimeout(func) .

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

Так вызов функции будет запланирован сразу после выполнения текущего кода.

Например, этот код выводит «Привет» и затем сразу «Мир»:

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

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

В браузере есть ограничение на то, как часто внутренние счётчики могут выполняться. В стандарте HTML5 говорится: «после пяти вложенных таймеров интервал должен составлять не менее четырёх миллисекунд.».

Продемонстрируем в примере ниже, что это означает. Вызов setTimeout повторно вызывает себя через 0 мс. Каждый вызов запоминает реальное время от предыдущего вызова в массиве times . Какова реальная задержка? Посмотрим:

Первый таймер запускается сразу (как и указано в спецификации), а затем задержка вступает в игру, и мы видим 9, 15, 20, 24. .

Аналогичное происходит при использовании setInterval вместо setTimeout : setInterval(f) запускает f несколько раз с нулевой задержкой, а затем с задержкой 4+ мс.

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

Этого ограничения нет в серверном JavaScript. Там есть и другие способы планирования асинхронных задач. Например, setImmediate для Node.js. Так что это ограничение относится только к браузерам.

Итого

  • Методы setInterval(func, delay, . args) и setTimeout(func, delay, . args) позволяют выполнять func регулярно или только один раз после задержки delay , заданной в мс.
  • Для отмены выполнения необходимо вызвать clearInterval/clearTimeout со значением, которое возвращают методы setInterval/setTimeout .
  • Вложенный вызов setTimeout является более гибкой альтернативой setInterval . Также он позволяет более точно задать интервал между выполнениями.
  • Планирование с нулевой задержкой setTimeout(func,0) или, что то же самое, setTimeout(func) используется для вызовов, которые должны быть исполнены как можно скорее, после завершения исполнения текущего кода.
  • Браузер ограничивает 4-мя мс минимальную задержку между пятью и более вложенными вызовами setTimeout , а также для setInterval , начиная с 5-го вызова.
Читайте также:  Не работает пульт от телевизора dexp что может быть

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

Например, таймер в браузере может замедляться по многим причинам:

  • Перегружен процессор.
  • Вкладка браузера в фоновом режиме.
  • Работа ноутбука от аккумулятора.

Всё это может увеличивать минимальный интервал срабатывания таймера (и минимальную задержку) до 300 или даже 1000 мс в зависимости от браузера и настроек производительности ОС.

Задачи

Вывод каждую секунду

Напишите функцию printNumbers(from, to) , которая выводит число каждую секунду, начиная от from и заканчивая to .

Сделайте два варианта решения.

  1. Используя setInterval .
  2. Используя рекурсивный setTimeout .

Источник

Javascript setInterval не работает

Мне нужно запускать функцию javascript каждые 10 секунд.

Я понимаю, что синтаксис должен работать как follow, но я не получаю никакого успеха:

но это не работает. Любой помочь?

4 ответов

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

код, для справки:

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

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

Итак, когда вы скажи:

вы фактически объявляете переменную func имеет значение funcName() . Но обратите внимание на скобки. funcName() фактически является возвращаемым значением funcName . Как я сказал выше, так как funcName фактически не возвращает никакого значения, по умолчанию это undefined . Другими словами, ваша переменная func на самом деле будет иметь значение undefined .

тогда у вас есть эта строка:

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

первый аргумент должен быть функцией, а не строкой. Если это строка, то движок JavaScript будет использовать eval на этой строке вместо этого. Другими словами, в setInterval выполняется следующий код JavaScript: , func — это просто переменная (со значением undefined , но это неуместный.) Таким образом, каждые десять секунд JS engine оценивает переменную func и возвращает undefined . Но это ничего не дает. Я имею в виду, технически это оценивается каждые 10 секунд, но вы не увидите никаких эффектов от этого.

решение это отдать setInterval функция для запуска вместо строки. Итак, в этом случае:

обратите внимание, что я не дал его func . Это потому что func is не функции в ваш код; это значение undefined , потому что вы назначили его funcName() . Как я сказал выше, funcName() вызываем функцию funcName и возвращает возвращаемое значение функции. С funcName ничего не возвращает, по умолчанию это undefined . Я знаю, что уже говорил это несколько раз, но это действительно очень важная концепция: когда вы видите funcName() , вы должны думать «возвращаемое значение funcName «. Когда вы хотите обратиться к , как отдельная сущность, вы следует оставить скобки, чтобы вы не называли это: funcName .

Читайте также:  Не работает одна форсунка инжектора ваз 2107

таким образом, другим решением для вашего кода будет:

однако это немного избыточно: зачем использовать func вместо funcName ?

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

в этом случае двигатель JS будет оценивать func() каждые десять секунд. Другими словами, он будет предупреждать «test» каждые десять секунд. Однако, как гласит знаменитая фраза, eval зло, поэтому вы должны стараться избегать этого, когда это возможно.

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

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

Источник

JS,Highcharts, не работает функция setInterval

Всем привет. Пытаюсь работать с графиками через Highcharts.

Есть файл php. Который отдает данные в след виде:

Далее пытаюсь эти данные добавить на график через след код:

$.getJSON асинхронная функция. Следовательно когда ты вызываешь series.addPoint([x, y], true, true); в своем коде, у тебя x, y еще не определены.

В понимании асинхронности вообще.

Должно быть так.

Значит ты либо некорректно внес изменения. Либо у тебя в lst не приходят корректные данные

Твой код точно выглядит так?

Твой код точно выглядит так? Что в lst приходит ты проверил?

Есть файл php. Который отдает данные в след виде:

это у тебя не lst[0] и lst[1]

У тебя приходит массив с массивом. Должно быть как минимум lst[0][0] и lst[0][1]

Как проверить lst? Прости за тупой вопрос, но с js я второй день знаком. Через alert?

Поправил код, теперь выглядит так, тоже не работает:

Открываешь devtools, вкладку Сеть, и смотришь какие запросы уходят на сервер и что приходит в ответ.

Иммобилизация (от лат. immobilis — неподвижный): создание неподвижности в повреждённой или больной части тела

Если я правильно посмотрел, то идут запросы на файл php, и выдается ошибка — 500 Internal Server Error

Ну так. У тебя проблема на сервере.

В браузере url до своего php файла открыть пробовал?

Да, выдает нужные мне данные в таком формате — [[1594920369000,45]]

Господи. Ну значит у тебя проблема с формированием запроса. Посмотри соответсвие правильности пути, заголовки, что овобще отсылается на сервер. Все есть в этой вкладке devtools. Если у тебя сервер на один запрос из браузера отвечает оке, а на другой не окей — очевидно же, что запросы разные и ты где-то ошибся.

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

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

Спасибо за подсказки и помощь, буду разбираться из-за чего ошибка.

Спасибо за подсказки и помощь, буду разбираться из-за чего ошибка.

Можно и так.
А можно и код показать.

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

Источник

Оцените статью