在Google Chrome中设置JavaScript超时限制

时间:2011-06-13 21:54:22

标签: javascript google-chrome

是否可以增加JavaScript的超时限制?

如果我的脚本执行时间超过20/30秒,则会弹出带有不负责任页面对话框的chrome。

制作更有效的脚本对我没有帮助,因为脚本有时需要迭代一个函数达百万或十亿次

3 个答案:

答案 0 :(得分:6)

在步骤/块上拆分功能并在setInterval(function(){})内运行。 这样,页面将响应,您将能够通知用户执行的进度,您将完成工作。

UPDATE :这是一个简单的功能 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);

答案 1 :(得分:3)

当你有很多处理来做客户端时,你需要将你的工作分成不同的线程。浏览器只有一个线程来处理用户输入(事件)和处理JS。如果你处理太多的JS而没有屈服,那么UI会变得没有响应,并且浏览器不满意。

如何让脚本产生?新方法是使用网络工作者http://www.whatwg.org/specs/web-workers/current-work/。这可以通过创建一个单独的线程来运行你的JS,线程线程不能访问DOM并且可以同时运行。

但是,这种新技术并不存在于所有浏览器中。对于旧版浏览器,您可以通过让脚本通过超时调用自身来分解您的工作。每当发生超时时,脚本都会让浏览器运行其事件,一旦浏览器完成,您的下一次超时将被触发。

示例 http://jsfiddle.net/mendesjuan/PucXf/

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


function sumOfSquares(list) {  
  var total = 0;
  for (var i = 0; i < list.length; i++) {
      total += list[i] * list[i];
      // DOM manipulation to make it take longer
      var node = document.createElement("div");
      node.innerHTML = "Sync temp value = " + total;
      document.body.appendChild(node);
  }
    return total;
}


function sumOfSquaresAsync(arr, callback) {
  var chunkSize = 1000; // Do 1000 at a time
  var arrLen = arr.length;
  var index = 0;
  var total = 0;  

  nextStep();

  function nextStep() {
     var step = 0;
     while (step < chunkSize && index < arrLen) {
       total += arr[index] * arr[index];
       // DOM manipulation to make it take longer
       var node = document.createElement("div");
       node.innerHTML = "Async temp value = " + total;
       document.body.appendChild(node);         
       index++;
       step++;
     }

     if (index < arrLen) {
        setTimeout(nextStep, 10);
     } else {
       callback(total);
     }
  }
}



sumOfSquaresAsync(list, function(total) {console.log("Async Result: " + total)});

//console.log("Sync result" + sumOfSquares(list));

关于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);        
})

答案 2 :(得分:3)

如果您的目标是禁止“杀死等待”消息作为慢速JavaScript的快速临时修复,则解决方案是在Google Chrome中打开工具/开发人员工具,并在浏览时将其保持打开状态并最小化桌面上的某个位置。 / p>