Если JavaScript-сценарий выполняется слишком долго (как правило это происходит в результате обработки огромного количества данных внутри цикла), то браузер выводит сообщение с предложением остановить работу сценария. Такое сообщение Internet Explorer выводит, к примеру, когда число синхронно выполняемых инструкций достигает максимума. (Установленное по умолчанию значение в размере 5 000 000 инструкций можно изменить в реестре Windows.) Этот механизм позволяет пользователю остановить сценарий, который выполняет бесконечный цикл или просто работает медленно.
На выполнение сценария разные браузеры накладывают разные ограничения.
Internet Explorer ставит ограничение в 5 миллионов инструкций.
Firefox ограничивает время выполнения сценария 10 секундами.
Safari ограничивает время выполнения сценария 10 секундами.
Chrome не ограничивает время выполнения сценария, но определяет, когда браузер падает или становится неработоспособным.
Opera никак не ограничивает время выполнения сценария.
Чтобы изменить ограничение таймаута в Internet Explorer версии 4.0 до 8 выполните следующие действия.
С помощью редактора реестра, например Regedt32.exe, откройте thiskey:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Styles
Создайте новое значение DWORD с именем MaxScriptStatements равным 0xFFFFFFFF во избежание появления диалогового окна.
По умолчанию данный ключ не существует. Если ключ не был добавлен, то предельное времени ожидания по умолчанию равно 5 000 000 инструкций для обозревателя Internet Explorer 4 и более поздних версий.
Для того, чтобы обойти ограничение на время выполнения сценария во всех браузерах, рекомендуется избегать рекурсий, заменяя их циклом while и разбивать долго выполняющийся циклы на части следующим образом.
var i = 0;
(function longCycle () {
for (; i < 6000000; i++) {
/*
Основное тело цикла
*/
// Каждые 100 000 итераций мы делаем принудительное прерывание цикла
if (i > 0 && i % 100000 === 0) {
// Вручную увеличиваем значение "i", так как мы делаем "break"
i++;
// Уставаливаем таймер для начала следующей итерации основного цикла
window.setTimeout(longCycle);
break;
}
}
})();
function RepeatingOperation (operation, yieldEveryIteration) {
var count = 0, instance = this;
this.step = function (args) {
if (++count >= yieldEveryIteration) {
count = 0;
setTimeout(function(){operation(args);}, 1, []);
return;
}
operation(args);
};
};
var test = new Array(initdata.length)
, i = 0
, ro = new RepeatingOperation(function(){
test2[i] = initdata[i] * 2;
if (++i < initdata.length) {
ro.step();
} else {
continueOperations();
}
}, 100);
ro.step();
Комментариев нет:
Отправить комментарий