Javascript setInterval
вопрос. Если я использую setInterval следующим образом:
setInterval('doSome();',60000);
Я уверен, что функция doSome()
запускается каждые 60 секунд, даже если я изменяю вкладку в браузере?
Ответы
Ответ 1
Передача строки в 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 мс, если вкладка не сфокусирована. (Ссылка)
Ответ 2
Нет, интервал не может выполняться до тех пор, пока цикл события не будет очищен, поэтому, если вы делаете, например, setInterval(func, 1000); for(;;)
, то интервал никогда не будет выполняться. Если другие вкладки браузеров выполняются в одном потоке (как и везде (?), За исключением хром, то то же самое происходит, если эти вкладки забивают цикл событий.)
Но для интервала, равного 60000
, по крайней мере, очень вероятно, что func будет вызван в разумное время. Но никаких гарантий.
Ответ 3
Если вкладка с функцией setInterval()
остается открытой, тогда да, функция будет выполняться каждые 60 секунд, даже если вы переключаетесь на или открываете другие вкладки.
Ответ 4
Да, это работает на примере, который я только что создал.
http://jsfiddle.net/5BAkx/
Ответ 5
Да, фокус браузера не имеет значения.
Однако вы не должны использовать строковый аргумент setInterval
. Вместо этого используйте ссылку на функцию:
setInterval(doSome, 60000);
Ответ 6
Нет, вам не гарантируется точная безопасность времени. JS основано на событиях (и одно-трехмерное), поэтому событие не срабатывает в нужный момент, особенно если у вас другой код работает одновременно на вашей странице.
Событие будет срабатывать в окрестности установленного значения времени, но не на точной миллисекунде. Ошибка может составлять десятки миллисекунд, даже если в то время не было другого события. Это может быть проблемой, если, например, у вас длительный процесс, когда важно время. Если вы это сделаете, вам потребуется синхронизировать с часами раз в то время.
Ответ 7
Да, он будет вызываться до тех пор, пока страница будет открыта, независимо от того, какая вкладка включена или даже браузер сведен к минимуму.
Однако убедитесь, что вы передаете функцию не строке для setInterval
он должен быть >
setInterval(doSome, 60000)
Ответ 8
О "точной безопасности времени": следующий код запускает 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.
}
}