Javascript задержка в цикле

Я работаю над сайтом, где мне нужно создать паузу или задержку. Поэтому, пожалуйста, скажите мне, как создать паузу или задержку в цикле for в javascript или jQuery

Это пример теста

Я пробовал все, но я думаю, что этот код лучше, это очень простой код.

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

Используйте setTimeout для запуска фрагментов кода позднее:

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

Следующий код — пример псевдо-многопоточности, который вы можете сделать в JS, это примерно пример того, как вы можете задержать каждую итерацию цикла:

Невозможно напрямую приостановить функцию Javascript в цикле for , а затем возобновить в этой точке.

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

startTime — это время, прежде чем вы запустите время но этот метод заставит браузеры стать очень медленными.

В то время как некоторые из других ответов будут работать, я считаю, что код менее элегантный. Библиотека Frame.js была разработана для решения этой проблемы. Используя Frame, вы можете сделать это следующим образом:

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

Я выполняю функцию, где мне нужен доступ к свойствам внешнего объекта. Итак, закрытие в Guffa решение для меня не работает. Я нашел вариант решения nicosantangelo, просто упакуя setTimeout в оператор if, чтобы он не запускался вечно.

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

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

  • 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 секунд… Вот псевдокод:

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

Рекурсивный 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-го вызова.

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

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

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

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

Задачи

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

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

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

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

решение

Я хотел бы добавить задержку/сон внутри while петли:

истинен только первый сценарий: после показа alert(‘hi’) , он будет ждать в течение 3 секунд, то alert(‘hello’) будет отображаться, но затем alert(‘hello’) будет многократно постоянно.

то, что я хотел бы, это после alert(‘hello’) отображается через 3 секунды после alert(‘hi’) тогда ему нужно подождать 3 секунды во второй раз alert(‘hello’) и так далее.

22 ответов

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

Читайте также:  Как проверить пинг интернет соединения

вы можете использовать что-то вроде этого:

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

попробуйте что-то вроде этого:

если вы используете ES6, вы можете использовать let достижения:

что let объявляется i для каждого шаг, а не петли. Таким образом, то, что передается setTimeout — это именно то, что мы хотим.

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

первый тайм-аут будет установлен до 3000 * 1 , второй до 3000 * 2 и так далее.

Я думаю, тебе нужно что-то вроде этого:

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

Я бы, вероятно, использовать setInteval . Вот так,

Это будет работать

Так как ES7 есть лучший способ ждут петли:

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

в ES6 (ECMAScript 2015) Вы можете выполнять итерацию с задержкой с помощью генератор и интервал.

генераторы, новая функция ECMAScript 6, являются функциями, которые могут быть сделал паузу и продолжил: Вызов genFunc не выполняет его. Вместо этого возвращает так называемый объект generator, который позволяет нам управлять genFunc исполнение. genFunc () первоначально приостанавливается в начале тело. В genObj способ.next () продолжает выполнение genFunc, пока следующий выход. (исследуя ES6)

пример кода:

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

Я делаю это с сине Promise.delay и рекурсии.

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

было бы эквивалентно:

Вы можете использовать RxJS интервал оператор. Интервал испускает целое число через каждые x секунд, и take Is указывает количество раз, когда он должен испускать числа

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

сначала определим некоторые существенные переменные:

Далее вы должны определить функцию, которую вы хотите запустить. Это будет передано i, текущий индекс цикла и длина цикла, Если вам это нужно:

самоисполнимости версия

функциональная версия

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

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

очевидно, вам нужна поддержка async/await для этого. Работает в узле 8.

для общего использования " забудьте обычные циклы "и используйте эту комбинацию" setInterval "включает"setTimeOut": вот так (из моих реальных задач).

PS: поймите, что реальное поведение (setTimeOut): все они начнут в то же время "три бла бла бла начнут отсчет в тот же момент", поэтому сделайте другой тайм-аут, чтобы организовать выполнение.

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