Функции setTimeout и setInterval


setTimeout и setInterval В JavaScript есть две функции для отложенного запуска кода: setTimeout и setInterval. Отличаются они тем, что setTimeout запускает код единожды, а setInterval — постоянно с заданной периодичностью. Обе функции первым аргументом принимают строку кода, которую необходимо выполнить, или функцию, которую необходимо запустить. Второй аргумент задаёт задержку в миллисекундах. Возвращают обе функции идентификатор созданного таймера. setTimeout('alert(1)', 2000); // Через две секунды выскочит сообщение setTimeout(function() { alert(1); }, 2000); // то же самое, но с функцией. Обратите внимание, что строка кода — это именно строка, заключённая в кавычки, а не просто код. Впрочем передавать строку не рекомендуется. Она выполняется в глобальной области видимости, а скрипты, как правило, находятся в какой-нибудь локальной области, в результате строка кода, передаваемая в setTimeout/setInterval не имеет доступа к данным и функциям скрипта. Да и неудобно это — писать код внутри строки, он даже не подсвечивается. function f() { var a = 1; setTimeout('alert(a)', 2000); // Через две секунды будет ошибка, // т.к. a не определена в глобальной области видимости. } function f() { var a = 1; setTimeout(function() { alert(a); }, 2000); // Через две секунды выскочит сообщение } Действие функций setTimeout и setInterval можно отменить функциями clearTimeout и clearInterval соответственно, передавая последним идентификатор отключаемого таймера. Простой пример: при наведении мышкой на элемент необходимо через две секунды показать сообщение. Однако если в течение этих двух секунд указатель мыши был убран с элемента, то сообщение показывать не нужно. var timerId; element.onmouseover = function() { timerId = setTimeout(function() { alert(1); }, 2000); }; element.onmouseout = function() { clearTimeout(timerId); }; Если в clearTimeout/clearInterval передан недействительный идентификатор, то ничего не произойдёт. Поэтому в примере выше можно не проверять, отработал ли уже таймер, и что вообще лежит в timerId. Принцип работы таймеров в JavaScript Многие начинающие в JavaScript разработчики путают принцип работы его таймеров с принципом работы имеющейся во многих языках функции sleep. sleep приостанавливает выполнение программы на определённый промежуток времени, после чего работа продолжается с того же места, где была остановлена. В JavaScript такое невозможно, по крайней мере в браузерном JavaScript. JavaScript язык однопоточный. Когда он выполняется в браузере, браузер никаких действий не производит. Если скрипт выполняется достаточно долго, становится заметно, что браузер "висит". Поэтому функция sleep вместе с приостановкой скрипта "вешала" бы браузер. Вместо этого функции setTimeout/setInterval "делают отметку", что необходимо запустить некий код через столько-то миллисекунд, а скрипт продолжает работать своим чередом. var n = 0; setTimeout(function() { alert(n); // На момент вывода сообщения n уже будет равна 5. }, 1); // Ставим минимально возможный интервал n = 5; // После установки таймера меняем значение переменной. Из того, что язык однопоточный следует ещё одно следствие — код выполнится не через строго заданный промежуток времени, а не раньше, чем через этот промежуток. Если в нужный момент времени будет выполняться какой-либо код, то интерпретатор дождётся его окончания, после чего только запустит код по таймеру. В Firefox функции setTimeout и setInterval передают своим callback-функциям один числовой параметр, равный количеству миллисекунд, на которые запоздал вызов функции. setTimeout(function(delta) { alert(delta); // Чем дольше будет открыто первое окно, тем большее число здесь будет. }); alert(1); К сожалению, в остальных браузерах данного функционала нет.