setTimeout или setInterval?
насколько я могу судить, эти две части javascript ведут себя одинаково:
В:
function myTimeoutFunction()
{
doStuff();
setTimeout(myTimeoutFunction, 1000);
}
myTimeoutFunction();
Вариант B:
function myTimeoutFunction()
{
doStuff();
}
myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);
есть ли разница между использованием setTimeout и setInterval?
19 ответов:
они по сути пытаются сделать то же самое, но
setIntervalподход будет более точным, чемsetTimeoutподходим, так какsetTimeoutждет 1000 мс, запускает функцию, а затем устанавливает другой тайм-аут. Таким образом, период ожидания на самом деле немного больше 1000 мс (или намного больше, если ваша функция занимает много времени для выполнения).хотя можно подумать, что
setIntervalвыполняет ровно каждые 1000 мс, важно отметить, чтоsetIntervalтакже задержит, так как JavaScript не является многопоточным языком, а это означает, что - если есть другие части сценария, - интервал должен будет подождать, пока это закончится.на эта скрипка, вы можете ясно видеть, что тайм-аут будет отставать, в то время как интервал почти все время почти на 1 вызов в секунду (что он пытается делать). Если вы измените переменную скорости вверху на что-то маленькое, например 20 (это означает, что он будет пытаться работать 50 раз в секунду), то интервал никогда не достигнет в среднем 50 итераций в секунду.
задержка почти всегда незначительна, но если вы программируете что-то действительно точное, вы должны пойти на саморегулирующийся таймер (который по существу является таймером на основе таймаута, который постоянно настраивается для задержки, которую он создал)
есть ли разница?
да. Тайм-аут выполняет определенное количество времени после вызова setTimeout (); интервал выполняет определенное количество времени после запуска предыдущего интервала.
вы заметите разницу, если ваша функция doStuff() занимает некоторое время для выполнения. Например, если мы представляем вызов setTimeout/setInterval с
., запуск тайм-аута / интервала с*и выполнение кода JavaScript с[-----], временные рамки выглядят так:Timeout: . * . * . * . * . [--] [--] [--] [--] Interval: . * * * * * * [--] [--] [--] [--] [--] [--]следующая сложность заключается в том, что интервал срабатывает, когда JavaScript уже занят чем-то (например, обработкой предыдущего интервала). В этом случае интервал запоминается и происходит, как только предыдущий обработчик завершает работу и возвращает управление браузеру. Так, например, для процесса doStuff (), который иногда короткий ([ - ]), а иногда и длинный ([-----]):
. * * • * • * * [-] [-----][-][-----][-][-] [-]• представляет собой интервал обжига, что не удалось выполнить его код сразу, и был сделан в ожидании вместо этого.
поэтому интервалы пытаются "догнать", чтобы вернуться по расписанию. Но они не стоят в очереди друг на друга: за интервал может быть только одно ожидание выполнения. (Если бы все они стояли в очереди, браузер остался бы с постоянно расширяющимся списком выдающихся казней!)
. * • • x • • x [------][------][------][------]x представляет собой интервальный запуск, который не может быть выполнен или выполнен в ожидании, поэтому вместо этого был отброшенный.
если ваша функция doStuff () обычно занимает больше времени, чем интервал, установленный для нее, браузер будет есть 100% CPU, пытаясь его обслуживать, и может стать менее отзывчивым.
что вы используете и почему?
Chained-Timeout дает браузеру гарантированный слот свободного времени; Interval пытается обеспечить выполнение функции, которую он запускает, как можно ближе к запланированному времени, за счет пользовательского интерфейса браузера доступность.
Я бы рассмотрел интервал для одноразовых анимаций, которые я хотел бы быть как можно более гладким, в то время как цепные таймауты более вежливы для текущих анимаций, которые будут иметь место все время, пока страница загружается. Для менее требовательных применений (таких как тривиальный запуск обновления каждые 30 секунд или что-то еще) вы можете безопасно использовать либо.
С точки зрения совместимости браузера, setTimeout предшествует setInterval, но все браузеры, которые вы встретите сегодня, поддерживают оба. Последний отставший в течение многих лет был IE Mobile в WinMo
setInterval ()
setInterval()- это метод выполнения кода на основе временного интервала, который имеет собственную возможность многократно запускать указанный скрипт при достижении интервала. Он должен не быть вложенным в его функцию обратного вызова автором сценария, чтобы сделать его цикл, так как он петли по умолчанию. Он будет продолжать стрелять в интервале, если вы не позвонитеclearInterval().если вы хотите, чтобы цикл код для анимации или на часы отметьте, затем используйте
setInterval().function doStuff() { alert("run your code here when time interval is reached"); } var myTimer = setInterval(doStuff, 5000);setTimeout ()
setTimeout()это метод выполнения кода на основе времени, который будет выполнять только скрипт один раз при достижении интервала. Это будет не повторите еще раз, если вы не передаете его в цикл сценария, вложивsetTimeout()объект внутри функции, которую он вызывает для запуска. Если зацеплено к петле, то оно будет держать снять на интервале если вы не вызываетеclearTimeout().function doStuff() { alert("run your code here when time interval is reached"); } var myTimer = setTimeout(doStuff, 5000);если вы хотите, чтобы что-то произошло один раз после указанного периода времени, то используйте
setTimeout(). Это связано с тем, что он выполняется только один раз при достижении указанного интервала.
функции setInterval делает его легче, чтобы отменить будущие выполнение кода. Если вы используете setTimeout, вы должны отслеживать идентификатор таймера, если вы хотите отменить его позже.
var timerId = null; function myTimeoutFunction() { doStuff(); timerId = setTimeout(myTimeoutFunction, 1000); } myTimeoutFunction(); // later on... clearTimeout(timerId);и
function myTimeoutFunction() { doStuff(); } myTimeoutFunction(); var timerId = setInterval(myTimeoutFunction, 1000); // later on... clearInterval(timerId);
найти
setTimeoutметод проще в использовании, если вы хотите отменить тайм-аут:function myTimeoutFunction() { doStuff(); if (stillrunning) { setTimeout(myTimeoutFunction, 1000); } } myTimeoutFunction();кроме того, если что-то пойдет не так в функции он просто перестанет повторять в первый раз ошибку, вместо того, чтобы повторять ошибку каждую секунду.
сама разница заключается в их целях.
setInterval() -> executes a function, over and over again, at specified time intervals setTimeout() -> executes a function, once, after waiting a specified number of millisecondsЭто просто
более подробные сведения здесь http://javascript.info/tutorial/settimeout-setinterval
при запуске какой-либо функции внутри setInterval, которая работает больше времени, чем тайм-аут - > браузер будет застрял.
- например,doStuff() занимает 1500 сек. для выполнения и вы делаете:setInterval(doStuff, 1000);
1) запуск браузера doStuff(), которая займет 1,5 сек. должны быть выполнены;
2) после ~1 секунды он пытается запустить doStuff() снова. Но предыдущий doStuff() все еще выполняется - > так браузер добавляет этот запуск в очередь (для запуска после первого делается).
3,4,..) То же самое добавление в очередь выполнения для следующих итераций, но doStuff() от предыдущих все еще в процессе...
в результате-браузер застрял.
чтобы предотвратить такое поведение, лучший способ-запустить setTimeout внутри setTimeout для эмуляции setInterval.
чтобы исправить тайм-ауты между вызовами setTimeout, вы можете использовать самокоррекции альтернатива в JavaScript setInterval техника.
Я использую setTimeout.
по-видимому, разница заключается в том, что setTimeout вызывает метод один раз, setInterval вызывает его повторно.
вот хорошая статья, объясняющая разницу: учебник: JavaScript таймеры с setTimeout и setInterval
в этой статье говорит, что вы должны избегать setInterval, если это возможно, тем более, что вы можете повторить его поведение с помощью setTimeout и получить некоторые дополнительные преимущества на этом пути.
Я сделал простой тест
setInterval(func, milisec), потому что мне было любопытно, что происходит, когда потребление времени функции больше, чем длительность интервала.
setIntervalбудет вообще запланируйте следующую итерацию сразу после start предыдущей итерации,если функция все еще продолжается. Если так, тоsetIntervalбудет ждать, пока функция не закончится. Как только это происходит, функция сразу же запускается снова - нет ожидания следующего итерация по расписанию (как это было бы при условиях без превышения функции времени). Также нет ситуации с параллельными итерациями.Я проверил это на Chrome v23. Я надеюсь, что это детерминированная реализация во всех современных браузерах.
window.setInterval(function(start) { console.log('fired: ' + (new Date().getTime() - start)); wait(); }, 1000, new Date().getTime());вывод на консоль:
fired: 1000 + ~2500 ajax call -. fired: 3522 <------------------' fired: 6032 fired: 8540 fired: 11048The
waitфункция-это просто помощник блокировки потока-синхронный вызов ajax, который принимает ровно 2500 миллисекунд обработки на стороне сервера:function wait() { $.ajax({ url: "...", async: false }); }
как setInterval, так и setTimeout возвращают идентификатор таймера, который можно использовать для отмены выполнения, то есть до запуска таймаутов. Чтобы отменить вызов clearInterval или clearTimeout, как это:
var timeoutId = setTimeout(someFunction, 1000); clearTimeout(timeoutId); var intervalId = setInterval(someFunction, 1000), clearInterval(intervalId);кроме того, тайм-ауты отменяются автоматически, когда вы покидаете страницу или закрыть окно браузера.
чтобы посмотреть на это немного по-другому: setInterval гарантирует, что код запускается с каждым заданным интервалом (т. е. 1000 мс или сколько вы указываете), а setTimeout устанавливает время, когда он "ждет", пока он не запустит код. И поскольку для запуска кода требуется дополнительные миллисекунды, он добавляет до 1000 мс и, таким образом, setTimeout снова запускается в неточное время (более 1000 мс).
например, таймеры / отсчеты не выполняются с помощью setTimeout, они выполняются с помощью setInterval, чтобы гарантировать, что он не задерживается и код выполняется с точно заданным интервалом.
Ну, setTimeout лучше в одной ситуации, как я только что узнал. Я всегда использую setInterval, который я оставил для запуска в фоновом режиме более получаса. Когда я переключился обратно на эту вкладку, слайд-шоу (на котором использовался код) менялось очень быстро, а не каждые 5 секунд, которые он должен был иметь. На самом деле это происходит снова, когда я тестирую его больше, и неважно, виноват ли браузер или нет, потому что с setTimeout эта ситуация полностью невозможно.
вы можете проверить ответ bobince самостоятельно при запуске следующего javascript или проверить это JSFiddle
<div id="timeout"></div> <div id="interval"></div> var timeout = 0; var interval = 0; function doTimeout(){ $('#timeout').html(timeout); timeout++; setTimeout(doTimeout, 1); } function doInterval(){ $('#interval').html(interval); interval++; } $(function(){ doTimeout(); doInterval(); setInterval(doInterval, 1); });
ваш код будет иметь различные intevals выполнения, и в некоторых проектах, таких как онлайн-игры это не приемлемо. Во-первых, что вы должны сделать, чтобы ваш код работал с теми же intevals, вы должны изменить "myTimeoutFunction" на это:
function myTimeoutFunction() { setTimeout(myTimeoutFunction, 1000); doStuff(); } myTimeoutFunction()после этого изменения, он будет равен
function myTimeoutFunction() { doStuff(); } myTimeoutFunction(); setInterval(myTimeoutFunction, 1000);но, вы все равно не будете иметь стабильный результат, потому что JS является однопоточным. На данный момент, если поток JS будет чем-то занят, он не сможет выполнить ваш функция обратного вызова, и выполнение будет отложено на 2-3 мс. У вас есть 60 исполнений в секунду, и каждый раз, когда у вас есть случайная задержка 1-3 сек, это будет абсолютно неприемлемо (через одну минуту это будет около 7200 МС задержки), и я могу посоветовать использовать что-то вроде этого:
function Timer(clb, timeout) { this.clb = clb; this.timeout = timeout; this.stopTimeout = null; this.precision = -1; } Timer.prototype.start = function() { var me = this; var now = new Date(); if(me.precision === -1) { me.precision = now.getTime(); } me.stopTimeout = setTimeout(function(){ me.start() }, me.precision - now.getTime() + me.timeout); me.precision += me.timeout; me.clb(); }; Timer.prototype.stop = function() { clearTimeout(this.stopTimeout); this.precision = -1; }; function myTimeoutFunction() { doStuff(); } var timer = new Timer(myTimeoutFunction, 1000); timer.start();этот код гарантирует стабильный период выполнения. Даже поток будет занят, и ваш код будет выполнен через 1005 МС, в следующий раз у него будет тайм-аут для 995 МС, и результат будет стабильно.
просто добавляя к тому, что уже было сказано, но версия setTimeout кода также достигнет
Maximum call stack sizeкоторый остановит его от функционирования. Поскольку нет базового случая для рекурсивной функции, чтобы остановиться, так что вы не можете запустить его навсегда.
вероятно, лучше заменить первую функцию на эту
Опции A'
function myTimeoutFunction() { setTimeout(myTimeoutFunction, 1000);// At first doStuff(); } myTimeoutFunction();не так ли ?
Я думаю
SetIntervalиSetTimeoutразные.SetIntervalвыполняет блок в соответствии с установленным временем while,SetTimeoutвыполняет блок программного кода один раз.попробуйте этот набор кодов после тайм-аута обратного отсчета секунд:
setInterval(function(e){ alert('Ugbana Kelvin'); }, 2000);а потом попробовать
setTimeout(function(e){ alert('Ugbana Kelvin'); }, 2000);вы можете увидеть разницу для себя.

Comments