javascript setInterval
Вопрос. Если я использую setInterval таким образом:
setInterval('doSome();',60000);
я в безопасности, что doSome()
Функция срабатывает каждые 60 секунд, даже если я изменю вкладку в браузере?
8 ответов
Передача строки setInterval
хорошо, и это один из двух способов использования setInterval
другой передает указатель на функцию. Это ни в коем случае не так, как в других ответах, но не так эффективно (как код должен быть обработан) и не является необходимым для вашей цели. И то и другое
setInterval('doSome();', 60000); // this runs doSome from the global scope
// in the global scope
а также
setInterval(doSome, 60000); // this runs doSome from the local scope
// in the global scope
являются правильными, хотя они имеют немного другое значение. Если doSome
локально для некоторой неглобальной области, вызов последней из той же области запускает локальную doSome
с интервалами 60000 мс. Вызов прежнего кода всегда будет искать doSome
в глобальном масштабе, и потерпит неудачу, если нет doSome
функция в глобальном масштабе.
Функция будет надежно запускаться независимо от фокуса табуляции с интервалами не менее 60000 мс, но обычно немного больше из-за накладных расходов и задержек.
Все браузеры ограничивают значение интервала, по крайней мере, до определенного значения, чтобы избежать слишком частых интервалов (я думаю, что это минимум 10 мс или 4 мс или что-то, я точно не помню).
Обратите внимание, что некоторые браузеры (грядущий Firefox 5 - один, но, вероятно, есть и другие, о которых я не знаю), еще один недостаток setInterval
радикально, например, до 1000 мс, если вкладка не сфокусирована. ( Ссылка)
Нет, интервал не может выполняться до тех пор, пока цикл событий не будет очищен, так что если вы делаете, например, setInterval(func, 1000); for(;;)
тогда интервал никогда не будет работать. Если вкладки других браузеров работают в одном и том же потоке (как и везде (?), За исключением chrome, то то же самое применимо, если эти вкладки засоряют цикл событий).
Но для такого большого интервала, как 60000
по крайней мере очень вероятно, что функция будет вызвана в разумные сроки. Но никаких гарантий.
Если вкладка с setInterval()
функция остается открытой, тогда да функция будет выполняться каждые 60 секунд, даже если вы переключаетесь на другие вкладки или открываете их.
Да, он будет вызываться, пока страница открыта, независимо от того, переключена ли вкладка или даже свернут ли браузер.
Однако убедитесь, что вы передаете функцию, а не строку в setInterval
это должно быть>
setInterval(doSome, 60000)
Да, фокус браузера не имеет значения.
Однако вы не должны использовать строковый аргумент для setInterval
, Вместо этого используйте ссылку на функцию:
setInterval(doSome, 60000);
Нет, вам не гарантируется точное время безопасности. JS основан на событиях (и однонаправленных), поэтому событие не сработает в нужный момент, особенно если у вас на странице одновременно работает другой код.
Событие будет происходить в окрестности установленного значения времени, но не в точную миллисекунду. Ошибка может составлять десятки миллисекунд, даже если в это время не выполняется другое событие. Это может быть проблемой, если, например, у вас есть длительный процесс, где важно время. Если вы это сделаете, вам нужно время от времени синхронизироваться с часами.
О "безопасности точного времени": начинается следующий код UpdateAll
с интервалами RefreshInterval
миллисекунды, с настройкой каждую секунду так, чтобы один запуск происходил в каждую секунду в начале секунды. Будет небольшая задержка для конечной скорости компьютера, но ошибки не будут накапливаться.
function StartAtEachSecond ()
{
var OneSecond = 1000; // milliseconds
var MinInteral = 50; // milliseconds, estimated safe interval
var StartTime = OneSecond - (new Date ()).getMilliseconds (); // Time until next second starts.
if (StartTime < MinInteral) StartTime += OneSecond
window.setTimeout (StartAtEachSecond, StartTime + MinInteral); // To set up the second after the next.
for (var Delay = 0.0; Delay < OneSecond - MinInteral; Delay += RefreshInterval)
{
window.setTimeout (UpdateAll, StartTime + Delay); // Runs during the next second.
}
}
Да, это работает на примере, который я только что создал.