Планирование в javascript: как применять функции settimeout и setinterval

Что нужно помнить о setTimeout () и setInterval ()

При работе с и следует помнить о нескольких вещах. Давайте рассмотрим их.

Есть ещё один способ использования : вы можете вызвать его рекурсивно для повторного запуска одного и того же кода вместо использования .

В приведённом ниже примере используется рекурсивный setTimeout () для запуска переданной функции каждые 100 миллисекунд:

Сравните приведённый выше пример со следующим — здесь используется для достижения того же эффекта:

Чем рекурсивный  отличается от ?

Разница между двумя версиями приведённого выше кода невелика.

  • Рекурсивный гарантирует такую же задержку между выполнениями. (Например, 100 мс в приведённом выше случае.) Код будет запущен, затем подождёт 100 миллисекунд, прежде чем запустится снова, поэтому интервал будет одинаковым, независимо от того, сколько времени требуется для выполнения кода.
  • Пример с использованием работает несколько иначе. Выбранный вами интервал включает время, затрачиваемое на выполнение кода, который вы хотите запустить. Предположим, что выполнение кода занимает миллисекунд — тогда интервал составляет всего миллисекунд.
  • При рекурсивном использовании каждая итерация может вычислять различную задержку перед запуском следующей итерации. Другими словами, значение второго параметра может указывать другое время в миллисекундах для ожидания перед повторным запуском кода.

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

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

Например, код приведённый ниже (рабочий код) выводит alert содержащий , затем alert содержащий  как только вы нажмёте ОК в первом alert.

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

clearTimeout () и используют один и тот же список записей для очистки. Интересно, что это означает, что вы можете использовать любой метод для очистки setTimeout () или setInterval ().

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

setInterval()

отлично работает, когда вам нужно один раз запустить код по истечении заданного периода времени. Но что происходит, когда вам нужно запускать код снова и снова — например, в случае анимации?

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

Давайте посмотрим на пример. Следующая функция создаёт новый объект , с помощью  извлекает из него строку с временем и отображает её в пользовательском интерфейсе. Затем он запускает функцию один раз в секунду с помощью , создавая эффект цифровых часов, которые обновляются раз в секунду ( реальный пример, и исходный код):

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

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

Активное обучение: Создание собственного секундомера!

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

Вам нужно отображать время, как и раньше, но в этом примере вам нужно:

  • Кнопка «Start» для запуска секундомера.
  • Кнопка «Stop» для паузы/остановки.
  • Кнопка «Reset», чтобы сбросить счётчик времени на .
  • Дисплей времени, чтобы отображать количество прошедших секунд а не фактическое время.

Несколько подсказок для вас:

  • Вы можете структурировать и стилизовать разметку кнопок по своему усмотрению; просто убедитесь, что вы используете семантический HTML с кавычками, которые позволяют захватывать ссылки на кнопки с помощью JavaScript.
  • Вероятно, вы захотите создать переменную, которая начинается с 0, а затем увеличивается на единицу каждую секунду с использованием постоянного цикла.
  • Этот пример проще создать без использования объекта Date (), как мы это делали в нашей версии, но он будет менее точен — вы не можете гарантировать, что колбэк сработает ровно через 1000 мс. Более точным способом было бы запустить startTime = Date.now (), чтобы получить метку времени, когда пользователь нажал кнопку запуска, а затем выполнить Date.now () — startTime, чтобы получить количество миллисекунд после того, как была нажата кнопка запуска .
  • Вам также нужно рассчитать количество часов, минут и секунд как отдельные значения, а затем отображать их вместе в строке после каждой итерации цикла. На втором счётчике вы можете отработать каждую из них.
  • Как вы могли бы их рассчитать? Подумайте об этом:
    • В одном часе секунд.
    • Количество минут — это количество секунд, оставшееся после вычитания всех часов, разделённое на 60.
    • Количество секунд будет количеством секунд, оставшихся после вычитания всех минут.
  • Вам необходимо включить начальный ноль в отображаемые значения, если сумма меньше , чтобы они больше походили на традиционные часы.
  • Чтобы приостановить секундомер, вам нужно очистить интервал. Чтобы сбросить его, вам нудно установить счётчик обратно на , очистить интервал, а затем немедленно обновить отображение.
  • Вероятно, вам следует отключить кнопку запуска после её нажатия один раз и снова включить её после того, как вы остановили / сбросили её. В противном случае многократное нажатие кнопки запуска приведёт к применению нескольких к часам, что приведёт к неправильному поведению.

Note: Если вы застряли, вы можете увидеть нашу версию (см. также исходный код ).

setInterval

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

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

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

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

Как формируется контекст исполнения

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

Как только скрипт попадает в интерпретатор, формируются глобальный контекст и глобальная область видимости, в которой держится Variable Object, или VO — объект переменных.

Он формируется из переменных вида Function Declaration и атрибутов функции по следующему принципу. Интерпретатор считывает код и находит все объявления:

  • переменных по ключевому слову var (const или let в ES6 и выше);
  • функций, объявленных ключевым словом function, без присваивания.

Это складывается в VO текущего контекста исполнения. Затем берётся Variable Object внешней области видимости и к нему добавляется сформированный выше VO. Сверху он дополняется параметрами функции и их значениями на момент исполнения.

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

Рассмотрим скрипт:

VO этого скрипта формируется:

  1. Из переменной a, значение которой — undefined.
  2. Переменной c, значение которой — undefined.
  3. Переменной b, значение которой — undefined.
  4. Функции func с соответствующим телом.

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

  1. В переменную a запишется значение 10.
  2. В переменную c запишется значение 7.
  3. В переменную b запишется значение 3.
  4. Будет вызвана функция func.
  5. Создается контекст исполнения функции func.
  6. В VO контекста исполнения функции func будут записаны переменные из внешней области видимости: a, c и b, c присвоенными значениями.
  7. В VO контекста исполнения функции func будут созданы переменные из списка аргументов; поскольку переменные a и b уже существуют в VO, добавлена будет только переменная d со значением undefined.
  8. В переменную a VO контекста исполнения функции func будет записано значение 10.
  9. В переменную b VO контекста исполнения функции func будет записано значение переменной a внешней области видимости — 10.
  10. В переменную d VO контекста исполнения функции func будет записано значение переменной b внешней области видимости — 3.
  11. Контекст исполнения функции func будет запущен.
  12. В консоль выведется 1010 7 3.
  13. В переменную c, находящуюся во внешней области видимости, будет записано значение 13.
  14. Контекст выполнения функции func будет завершён; VO функции func будет удалён.
  15. В консоль выведется 13.

Теперь перепишем скрипт, добавив setTimeout с нулевым тайм-аутом у вызова функции:

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

Состояния гонки

Каждое окно (и фрейм) обладает собственной очередью.

В Opera каждое окно обладает собственным потоком JavaScript. Это включает окна в . Результатом этого является то, что обработчики событий, запущенные из различных фреймов, могут выполняться одновременно. Если эти одновременные скрипты обращаются к разделённым данным (например, свойствам главного окна), появляется возможность возникновения состояний гонок (race conditions).

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

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

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

// плохая функция onload в frame:
window.top.notifyFrameLoaded()

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

// хорошая функция onload в frame
window.parent.setTimeout(window.top.notifyFrameLoaded, 0)

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

Подготавливаем HTML и CSS

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

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>requestAnimationFrame Demo</title><link rel="stylesheet" href="style.css"></head><body> <div id="page-wrapper"> <h1>requestAnimationFrame Demo</h1><div class="controls"> <button type="button" id="startBtn">Start Animation</button> <button type="button" id="stopBtn">Stop Animation</button> <button type="button" id="resetBtn">Reset</button> </div><canvas id="stage" width="640" height="100"></canvas> </div><script src="raf-polyfill.js"></script> <script src="script.js"></script></body></html>

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

Стоит обратить внимание, что тут есть два файла в

Убедитесь в том, что вы скачали этот файл и сохранили его в той же директории, что и . Вам также надо будет скопировать style.css отсюда в папку вашего проекта.

setTimeout vs window.setTimeout

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

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

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

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

Создаём callback

Достаточно разговоров, давайте создадим callback!

Во-первых, откройте Chrome Developer Console (Windows: Ctrl + Shift + J)(Mac: Cmd + Option + J) и введите следующий код функции:

function doHomework(subject) {alert( Starting my ${subject} homework. );}

Итак, выше мы создали функцию . Наша функция берёт одну переменную, это . Вызовите функцию, введя следующее в вашу консоль:

doHomework('math');// Alerts: Starting my math homework.

Теперь давайте добавим callback — как последний параметр в функции , мы можем передать callback. Callback-функция теперь является вторым аргументом вызова .

function doHomework(subject, callback) {alert( Starting my ${subject} homework. );callback();}doHomework('math', function() {alert('Finished my homework');});

Как вы видите, введя код выше в вашу консоль, вы получите один за другим два оповещения. Первое starting homework и второе, которое последует за ним finished homework.

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

function doHomework(subject, callback) {alert( Starting my ${subject} homework. );callback();}function alertFinished(){alert('Finished my homework');}doHomework('math', alertFinished);

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

Настраиваем JavaScript

Теперь, как только вы разобрались с HTML и CSS, настало время писать JavaScript код, который будет обрабатывать отрисовку анимации в . Если до этого вы не использовали Canvas API, то не беспокойтесь, я объясню всё что нужно по мере прочтения статьи.

Создайте новый файл в папке проекта под название и добавьте туда этот код:

(function() {// Get the buttons.var startBtn = document.getElementById('startBtn');var stopBtn = document.getElementById('stopBtn');var resetBtn = document.getElementById('resetBtn');// Остальной код будет тут…}());

Вы создали три переменные и ассоциировали их с кнопками из разметки.

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

// Canvasvar canvas = document.getElementById('stage');// 2d контекст отрисовки.var ctx = canvas.getContext('2d');// Стиль наполнения для контекста отрисовки.ctx.fillStyle = '#212121';// Переменная в которой будет храниться requestID.var requestID;// Переменные для отрисовки позиций и объекта.var posX = 0;var boxWidth = 50;var pixelsPerFrame = 5; // Количество пикселей, на которое должен двинуться блок в каждом кадре.// Отрисовка изначального блока в canvas.ctx.fillRect(posX, 0, boxWidth, canvas.height);

Тут сначала мы создаем переменную под названием сanvas и ассоциируем её с элементом из разметки. Далее вы задаёте 2d контекст отрисовки для него. Это даёт нам методы для отрисовки объектов на нём, так же как и методы контроля стилей этих объектов.

Следующая строка кода выставляет свойству для контекста отрисовки .

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

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

Под конец вы вызываете контекст отрисовки методом , передав ему X и Y координаты положения прямоугольника вместе с его высотой и шириной.

Макрозадачи и Микрозадачи

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

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

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

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

Например:

Какой здесь будет порядок?

  1. появляется первым, т.к. это обычный синхронный вызов.
  2. появляется вторым, потому что проходит через очередь микрозадач и выполняется после текущего синхронного кода.
  3. появляется последним, потому что это макрозадача.

Более подробное изображение событийного цикла выглядит так:

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

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

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

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

Обратите внимание – отрисовка страницы происходит только в самом конце. Как и в случае обычного синхронного кода

Асинхронность в JavaScript

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

Александр Кузьмин

ведущий программист, руководитель отдела клиентской разработки компании IT-Park

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

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

В JavaScript асинхронность — основной инструмент. Во времена до появления Node.JS он был практически единственным языком исполнения сценариев на клиенте в вебе (Internet Explorer поддерживал VB Script, но его никто не использовал). Сейчас невозможно представить интернет, где все запросы на сервер отправлялись бы с перезагрузкой страницы. Напротив, мы пришли к одностраничному вебу, в котором на стороне клиента происходит разрешение адресов страниц и отображение соответствующего контента.

Любые данные от сервера запрашиваются асинхронно: отправляется запрос (XMLHttpRequest или XHR), и код не ждёт его возвращения, продолжая выполняться. Когда же сервер отвечает, объект XHR получает уведомление об этом и запускает функцию обратного вызова — callback, который передали в него перед отправкой запроса.

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

Суть кроется в устройстве языка:

Возвращаемое значение (return)

Оператор предназначен для возвращения значения выражения в качестве результата выполнения функции. Значение выражения должно быть указано после ключевого слова .

Если оно не указано, то вместо этого значения будет возвращено .

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

С использованием :

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

Функция, которая возвращает функцию

В качестве результата функции мы можем также возвращать функцию.

Например:

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

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

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

Функцию, приведённую в коде мы можем также создать и так:

Кроме этого в качестве результата мы можем также возвратить внешнюю функцию:

Рекурсия

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

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

Например, использование рекурсии для вычисления факториала числа:

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

Перегрузка функций в JavaScript

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

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

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

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

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

Метод setTimeout

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

Основной и наиболее часто используемый синтаксис этой функции:

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

function greet () {
alert ('Welcome!');
}
setTimeout (greet, 2000) ; // приветствие появится через 2000 миллисекунд (2 секунды)

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

Посмотрим, как это реализовать:

const loggedInUser = 'Джон' ;
function greet (userName) {
alert ('Добро пожаловать' + userName + '!');
}
setTimeout (greet, 2000, loggedInUser);

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

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

Глядя на код предыдущего примера у вас может возникнуть соблазн передать аргументы в качестве параметров функции обратного вызова. Например:

или

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

Чтобы исправить эту ошибку, просто измените шаблон вызова, удалите скобки после имени функции, добавив аргументы (если они есть) в конец списка параметров . 

Немного информатики

Как было отмечено выше,

Напишем на псевдокоде классическую схему:

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

Циклы, как механизм программирования, нужны, главным образом, для упрощения написания кода. Вполне очевидно, что создавать программу, выполняющую определённую операцию для каждой точки 4К дисплея в отсутствии циклов — это вручную повторять описание нужной команды 4096*2160 раз. Много? Безусловно.

Применение в этой задаче всего одного цикла позволит сократить длину кода, как минимум, на 6 порядков. А если представить, что ту же самую программу нужно переписать для 8К монитора, то, вместо изменения всего одной инструкции в счетчике цикла, вам придётся дописывать ещё пару десятков миллионов строк кода, что является попросту недопустимым по своей величине и трудозатратам объёмом.

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

setInterval()

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

setInterval ( expression, interval );

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

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

// Hello показывается каждые 3 секундыlet timerId= setInterval(() => alert('Hello'), 3000);// Повторения прекращаются после 6 секунд с id таймера.setTimeout(() => { clearInterval(timerId); alert('Bye'); }, 6000);

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

requestAnimationFrame()

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

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

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

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: