Установка ограничения времени ожидания JavaScript в Google Chrome - PullRequest
8 голосов
/ 14 июня 2011

Можно ли увеличить ограничение времени ожидания для JavaScript?

Если у меня есть сценарий, который выполняется более 20/30 секунд, Chrome отобразится безответственным диалогом страницы.

Создание более эффективного скрипта мне не поможет, потому что скрипту иногда приходится перебирать функцию миллион или миллиард раз

Ответы [ 3 ]

6 голосов
/ 14 июня 2011

Чтобы разделить функцию на шаги / порции и запустить их внутри setInterval(function(){}).Таким образом, страница будет отзывчивой, вы сможете уведомлять пользователя о ходе выполнения и выполнять свою работу.

ОБНОВЛЕНИЕ : вот простая функция, которая принимает функцию workerвыполняя каждую итерацию, chunksz - количество итераций, запущенных в одном чанке maxit - общее количество итераций.

function task(worker, chunksz, maxit)
{
  var idx = 0;
  var xint = null;
  function exec_chunk() 
  {
     for(var n = 0; n < chunksz; ++n)
     {
       if(idx >= maxit) { return; }
       worker(idx++);
     }
     setTimeout(exec_chunk,1);
  }
  exec_chunk();
}

Вот пример: http://jsfiddle.net/Ed9wL/ Как видите, вы получаете всеитерации по порядку.

UPDATE2 :

Допустим, у вас есть цикл:

 for(var i=0; i<100000; ++i) { ... do something ... }

, затем вам нужно обернуть тело цикла ви вызовите task выше с этим как это:

task(function(i){ ... do something ... },100, 100000);

или как это:

function loopBody(i){ ... do something ... }
task(loopBody,100, 100000);
3 голосов
/ 06 июня 2012

Если ваша цель состоит в том, чтобы подавить сообщение «Kill-Wait» как быстрое временное исправление для вашего медленного JavaScript, тогда решение состоит в том, чтобы открыть Инструменты / Инструменты разработчика в Google Chrome и держать его открытым и свернутым где-нибудь на рабочем столе во время просмотра.

3 голосов
/ 14 июня 2011

Когда у вас много обработки на стороне клиента, вам нужно разделить свою работу на отдельные потоки.В браузере есть только один поток для обработки пользовательского ввода (событий) и для обработки JS.Если вы обрабатываете слишком много JS, не уступая, пользовательский интерфейс перестает отвечать на запросы, а браузер недоволен.

Как вы можете позволить своему скрипту работать?Новый способ заключается в использовании веб-работников http://www.whatwg.org/specs/web-workers/current-work/.Это работает путем создания отдельного потока для запуска JS, поток потока не имеет доступа к DOM и может выполняться одновременно.

Однако эта новая технология существует не во всех браузерах.В старых браузерах вы можете разделить свою работу, заставив сам скрипт вызываться по таймаутам.Всякий раз, когда происходит тайм-аут, скрипт передает браузеру свои события, после того как браузер завершит работу, ваш следующий тайм-аут будет запущен.1013 *

В примере на jsfiddle закомментирован синхронный вызов, вы можете вернуть его обратно, чтобы браузер начал сканировать.Обратите внимание, что асинхронный вызов занимает много времени, но он не вызывает длительное сообщение сценария и позволяет вам взаимодействовать со страницей во время вычислений (выбор текста, эффекты наведения кнопок).Вы можете увидеть, как он печатает частичные результаты на панели справа внизу.

ОБНОВЛЕНИЕ http://jsfiddle.net/mendesjuan/PucXf/8/

Давайте попробуем использовать функцию задачи c-smile для реализации суммыквадраты.Я думаю, что ему не хватает параметра, функции для обратного вызова, когда задача завершена.Использование task позволяет нам создавать несколько чанкованных функций без дублирования работы вызова setTimeout и итерации.

/**
 * @param {function} worker. It is passed two values, the current array index, 
 *        and the item at that index
 * @param {array} list Items to be traversed
 * @param {callback} The function to call when iteration is finished;
 * @param {number} maxit The number of iterations of the loop to run 
 *        before yielding, defaults to 1000
 */
function task(worker, list, callback, maxit)
{
  maxit = maxit || 1000; 
  var idx = 0;
  exec_chunk();
  function exec_chunk() 
  {
     for(var n = 0; n < maxit; ++n)
     {
       if(idx >= list.length) {
         callback(); 
         return;
       }
       worker(idx, list[idx]);
       idx++;
     }
     setTimeout(exec_chunk,1);
  }
}


function sumOfSquaresAsync(list, callback) 
{
   var total = 0;

   // The function that does the adding and squaring
   function squareAndAdd(index, item) {
      total += item * item;
      // DOM manipulation to make it take longer and to see progress
      var node = document.createElement("div");
      node.innerHTML = "Async temp value = " + total;
      document.body.appendChild(node);                
   }

   // Let the caller know what the result is when iteration is finished
   function onFinish() {
      callback(total);
   }

   task(squareAndAdd, list, onFinish);

}

var list = [];
for (var i = 0; i < 100000; i++) {
   list.push(Math.random());
}

sumOfSquaresAsync(list, function(total) {
    console.log("Sum of Squares is " + total);        
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...