Отмена исполнения clearTimeout
Функция setTimeout возвращает числовой идентификатор таймера timerId , который можно использовать для отмены действия. Синтаксис:
var timerId = setTimeout(...); clearTimeout(timerId);
В следующем примере мы ставим таймаут, а затем удаляем (передумали). В результате ничего не происходит.
var timerId = setTimeout(function() { alert(1) }, 1000); alert(timerId); // число ‐ идентификатор таймера
clearTimeout(timerId);
alert(timerId); // всё ещё число, оно не обнуляется после отмены
Как видно из alert , в браузере идентификатор таймера является обычным числом. Другие JavaScript‑окружения, например Node.JS, могут возвращать объект таймера, с дополнительными методами.
Такие разночтения вполне соответствуют стандарту просто потому, что в спецификации JavaScript про таймеры нет ни слова.
Таймеры – это надстройка над JavaScript, которая описана в секции Timers стандарта HTML5 для браузеров и в документации к Node.JS – для сервера.
setInterval
Метод setInterval имеет синтаксис, аналогичный setTimeout .
var timerId = setInterval(func / code, delay[, arg1, arg2...])
Смысл аргументов – тот же самый. Но, в отличие от setTimeout , он запускает выполнение функции не один раз, а регулярно повторяет её через указанный интервал времени. Остановить исполнение можно вызовом clearInterval(timerId) .
Следующий пример при запуске станет выводить сообщение каждые две секунды, пока не пройдёт 5 секунд:
// начать повторы с интервалом 2 сек var timerId = setInterval(function() {
alert( "тик" );
}, 2000);
// через 5 сек остановить повторы setTimeout(function() {
clearInterval(timerId); alert( 'стоп' );
}, 5000);
Рекурсивный setTimeout
Важная альтернатива setInterval – рекурсивный setTimeout :
/** вместо:
var timerId = setInterval(function() { alert( "тик" );
}, 2000);
*/
var timerId = setTimeout(function tick() {
alert( "тик" ); timerId = setTimeout(tick, 2000);
}, 2000);
В коде выше следующее выполнение планируется сразу после окончания предыдущего.
Рекурсивный setTimeout – более гибкий метод тайминга, чем setInterval , так как время до следующего выполнения можно запланировать по‑ разному, в зависимости от результатов текущего.
Например, у нас есть сервис, который в 5 секунд опрашивает сервер на предмет новых данных. В случае, если сервер перегружен, можно увеличивать интервал опроса до 10, 20, 60 секунд… А потом вернуть обратно, когда всё нормализуется.
Если у нас регулярно проходят грузящие процессор задачи, то мы можем оценивать время, потраченное на их выполнение, и планировать следующий запуск раньше или позже.
Рекурсивный setTimeout гарантирует паузу между вызовами, setInterval – нет.
Давайте сравним два кода. Первый использует setInterval :
var i = 1; setInterval(function() {
func(i);
}, 100);
Второй использует рекурсивный setTimeout :
var i = 1; setTimeout(function run() {
func(i); setTimeout(run, 100);
}, 100);
При setInterval внутренний таймер будет срабатывать чётко каждые 100 мс и вызывать func(i) :
Вы обратили внимание?…
Реальная пауза между вызовами func при setInterval меньше, чем указана в коде!
Это естественно, ведь время работы функции никак не учитывается, оно «съедает» часть интервала. Возможно и такое что func оказалась сложнее, чем мы рассчитывали и выполнялась дольше, чем 100 мс.
В этом случае интерпретатор будет ждать, пока функция завершится, затем проверит таймер и, если время вызова setInterval уже подошло (или прошло), то следующий вызов произойдёт сразу же.
Если функция и выполняется дольше, чем пауза setInterval , то вызовы будут происходить вообще без перерыва.
Исключением является IE, в котором таймер «застывает» во время выполнения JavaScript. А так будет выглядеть картинка с рекурсивным setTimeout :
При рекурсивном setTimeout задержка всегда фиксирована и равна 100 мс.
Это происходит потому, что каждый новый запуск планируется только после окончания текущего.
Do'stlaringiz bilan baham: |