在 Google Chrome 中设置 JavaScript 超时限制
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6336844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting JavaScript Timeout limit in Google Chrome
提问by Tyilo
Is it possible to increase the time out limit for JavaScript?
是否可以增加 JavaScript 的超时限制?
If I have a script that executes for more than 20/30 seconds chrome will pop-up with the unresponsable page dialog.
如果我的脚本执行时间超过 20/30 秒,chrome 将弹出无响应页面对话框。
Making a more efficient script won't help me because the script sometimes need to iterate through a function for a million or billion times
制作一个更高效的脚本对我没有帮助,因为脚本有时需要遍历一个函数一百万或十亿次
采纳答案by c-smile
To split the function on steps/chunks and run those inside setInterval(function(){})
.
This way page will be responsive, you will be able to notify user about progress of execution and you will get your job done.
在步骤/块上拆分函数并在setInterval(function(){})
. 这样页面将具有响应性,您将能够通知用户执行进度,您将完成工作。
UPDATE: Here is simple function that takes
worker
function executing each iteration,
chunksz
- number of iteration running in single chunk
maxit
- total number of iterations.
更新:这是一个简单的函数,它
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();
}
Here is an example : http://jsfiddle.net/Ed9wL/As you see you get all iterations in order.
这是一个示例:http: //jsfiddle.net/Ed9wL/正如您所见,您按顺序获得所有迭代。
UPDATE2:
更新2:
Say you have a loop:
假设你有一个循环:
for(var i=0; i<100000; ++i) { ... do something ... }
then you need to wrap body of the loop into a function and call the task
above with it like this:
然后你需要将循环体包装成一个函数并task
像这样调用上面的:
task(function(i){ ... do something ... },100, 100000);
or like this:
或者像这样:
function loopBody(i){ ... do something ... }
task(loopBody,100, 100000);
回答by Juan Mendes
When you have lots of processing to do client side, you need to split out your work into separate threads. The browser only has a single thread for handling user input (events) and for processing JS. If you're processing too much JS, without yielding, the UI becomes unresponsive and the browser is not happy.
当您有大量处理要做客户端时,您需要将您的工作拆分为单独的线程。浏览器只有一个线程来处理用户输入(事件)和处理 JS。如果你处理了太多的 JS 而没有让步,UI 就会变得没有响应,浏览器也会不满意。
How can you allow your script to yield? The new way is to use web workers http://www.whatwg.org/specs/web-workers/current-work/. This works by creating a separate thread to run your JS, thread thread does not access to the DOM and can be run concurrently.
你怎么能让你的脚本屈服?新方法是使用 web workers http://www.whatwg.org/specs/web-workers/current-work/。这是通过创建一个单独的线程来运行您的 JS 来实现的,线程线程不访问 DOM 并且可以并发运行。
However, this newer technology doesn't exist in all browsers. For older browsers, you can split up your work by having the script call itself through timeouts. Whenever a timeout occurs, the script is yielding to the browser to run its events, once the browser is done, your next timeout will be triggered.
然而,并非所有浏览器都存在这种较新的技术。对于较旧的浏览器,您可以通过让脚本通过超时调用自身来拆分您的工作。每当超时发生时,脚本都会让浏览器运行其事件,一旦浏览器完成,您的下一次超时将被触发。
Examplehttp://jsfiddle.net/mendesjuan/PucXf/
示例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));
The example on jsfiddle has the synchronous call commented out, you can put it back in to see the browser come to a crawl. Notice that the asynchronous call does take a long time to complete, but it doesn't cause the long running script message and it lets you interact with the page while calculating (select text, button hover effects). You can see it printing partial results on the pane to the bottom right.
jsfiddle上的例子把同步调用注释掉了,你可以把它放回去看浏览器爬行。请注意,异步调用确实需要很长时间才能完成,但它不会导致长时间运行的脚本消息,它允许您在计算时与页面交互(选择文本、按钮悬停效果)。您可以看到它在右下角的窗格上打印部分结果。
UPDATEhttp://jsfiddle.net/mendesjuan/PucXf/8/
更新http://jsfiddle.net/mendesjuan/PucXf/8/
Let's try to use c-smile's task function to implement sum of squares. I think he's missing a parameter, a function to call back when the task is finished. Using task
allows us to create multiple chunked functions without duplicating the work of calling setTimeout and iteration.
我们尝试使用c-smile的任务函数来实现平方和。我认为他缺少一个参数,一个在任务完成时回调的函数。Usingtask
允许我们创建多个分块函数,而无需重复调用 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);
})
回答by alpav
If your goal is to suppress "Kill-Wait" message as quick temporary fix for your slow JavaScript then the solution is to open Tools/Developer Tools in Google Chrome and keep it open and minimized somewhere on your desktop while browsing .
如果您的目标是抑制“Kill-Wait”消息作为您缓慢的 JavaScript 的快速临时修复,那么解决方案是在 Google Chrome 中打开工具/开发人员工具,并在浏览时保持打开并最小化桌面上的某处。