javascript 如何防止慢速脚本警告并强制浏览器继续运行脚本直到它完成?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6598285/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 21:14:00  来源:igfitidea点击:

How do I prevent the slow script warning and force the browser to continue running script until it's finished?

javascript

提问by Tyler Biscoe



UPDATE (5 July 2013):

更新(2013 年 7 月 5 日):

I've learned much since I originally asked this question. In one of the comments below it was suggested that I re-approach the task and find a way to solve it without risk of blocking the UI. I said it was impossible, the function must run as is. I don't actually remember what I was trying to accomplish with the function, but I'm certain that the commenter was right, and I was wrong. If you stumble upon this question and are in a similar situation as I was, then consider very seriously the possibility that your approach is flawed.

自从我最初问这个问题以来,我学到了很多。在下面的一条评论中,有人建议我重新处理该任务并找到一种方法来解决它,而不会冒阻塞 UI 的风险。我说这是不可能的,该功能必须按原样运行。我实际上不记得我试图用这个函数完成什么,但我确信评论者是对的,我错了。如果您偶然发现了这个问题并且与我处于类似的情况,那么请非常认真地考虑您的方法有缺陷的可能性。

You might also want to look into web workers.

您可能还想了解网络工作者

Here is where you can expect them to work.

在这里,您可以期待它们发挥作用。



Original Question:

原问题:

Rather than get overly specific to my problem, I'll keep this generic so other people who stumble upon this can find it useful.

与其对我的问题过于具体,我会保持这种通用性,以便其他偶然发现它的人会发现它很有用。

I have a function that accepts one parameter, a string. If the string is short the function runs fine and completes in a timely fashion. If, however, the string that's passed in is too long the script runs for a bit, then eventually times out and returns the browser's slow script dialog that allows the user to kill the script.

我有一个接受一个参数的函数,一个字符串。如果字符串很短,则函数运行良好并及时完成。但是,如果传入的字符串太长,脚本会运行一段时间,然后最终会超时并返回浏览器的慢速脚本对话框,允许用户终止脚本。

I would like to prevent that from happening so the script can continue to its terminus.

我想防止这种情况发生,以便脚本可以继续到它的终点。

How can this be done?

如何才能做到这一点?

A side note: If I can get this working, I would also like to make a status bar, similar to the one you see when loading gmail, appear so the user knows things are happening.

旁注:如果我可以让它工作,我还想制作一个状态栏,类似于您在加载 gmail 时看到的状态栏,出现以便用户知道正在发生的事情。

Thanks!

谢谢!

采纳答案by jAndy

No way you can disable that behavior in any browser by script. Imagine the impact, disable that feature and call a while(1). Pretty bad.

您无法通过脚本在任何浏览器中禁用该行为。想象一下影响,禁用该功能并调用while(1). 很糟糕。

It's on you to create code which does notblock the browser for "too long". There are a ton if best-practice patterns. I always recommend to try to break down your algorythm into smaller chunks. Combine that with a runaway-timer and a loop which makes sure that any operation does not run for longer than 100ms (for instance).

您可以创建不会在“太长时间”内阻止浏览器的代码。有很多最佳实践模式。我总是建议尝试将你的算法分解成更小的块。将其与失控计时器和循环相结合,以确保任何操作的运行时间不会超过 100 毫秒(例如)。

var sequence = ['foo', 'bar', 'baz', 'base', 'ball', 'hello', 'world', '100k more'],
    start = Date.now();

setTimeout(function _worker() {
    do {
       var element = sequence.shift();
       // do something with element
    } while( sequence.length && (Date.now() - start < 100) );

    if( sequence.length )
        setTimeout(_worker, 25);
}, 25);

回答by Felipe Sabino

You can try not blocking the UI completely and make it run "in another thread" with setTimeout.

您可以尝试不完全阻塞 UI 并使用setTimeout.

window.setTimeout(function() { ... code ... }, 0);

I say "in another thread" because there is no real multi-thread in JS, and hereis an nice article about it

我说“在另一个线程中”是因为在 JS 中没有真正的多线程,这里有一篇关于它的好文章



EDIT: (To make this answer more up-to-date with web technologies)

编辑:(为了使这个答案更符合网络技术的最新情况)

You can also use HTML 5 Web Workers depending on the browser you are targeting

您还可以根据您的目标浏览器使用HTML 5 Web Workers

回答by bcmoney

Unless your code is really aggressively bad or malicious, this almost always happens exclusively in IE 9 and below when an innocent script has loops that take too long to execute or an AJAX call is made to a slow server or there's lots of data to be returned and it exceeds allowed limits.

除非您的代码真的非常糟糕或恶意,否则这几乎总是只发生在 IE 9 及更低版本中,当无辜的脚本具有执行时间过长的循环或对慢速服务器进行 AJAX 调用或有大量数据要返回时它超过了允许的限制。

So, you could get your users to follow Microsoft's official fix for this issue here if it really bothers them: http://support.microsoft.com/kb/175500If they run this Microsoft FixIT patchwhich increases their default MaxScriptStatementsfrom the default 5,000,000 statements to the maximum allowed (represented by hex value 0xFFFFFFwhich is equal to 4,294,967,295 total statements of execution) it should fix the problem unless as I mentioned, the code was particularly bad or in need of refactoring.

因此,您可以让您的用户在此处关注 Microsoft 针对此问题的官方修复程序,如果它真的困扰他们:http: //support.microsoft.com/kb/175500如果他们运行此Microsoft FixIT 补丁程序,它会从默认值增加他们的默认MaxScriptStatements最多允许 5,000,000 条语句(由十六进制值0xFFFFFF表示, 等于 4,294,967,295 条总执行语句)它应该可以解决问题,除非我提到过,代码特别糟糕或需要重构。

In summary, your options are thus:

总之,您的选择是:

  1. best solution - fix your script... breakup loops and/or halt recursion after N number executions, and ensure AJAX requests are asynchronous not synchronouswhere possible, especially in loops

  2. alternative hack - use HTML5 WebWorkers, but better use WebWorker detectionfirst to see if your browsersupports them, and use a WebWorker shim library like thisor thisif not supported

  3. mediocre hack - setTimeoutwith a real script execution Timerand breaking loops up into iterations, could have edge cases that cause worse problems...

  4. terrible hack - ActiveX registry writing, better use proper browser detectionplus feature detection

  5. best workaround - Microsoft FixIT patch, if its just a small subset of users, have Tech Support send them to the official Microsoft FixIT page (or do it yourself) which more reliably adds the appropriate registry entries to increase script execution count

  1. 最佳解决方案 -修复您的脚本...在 N 次执行后中断循环和/或停止递归,并确保 AJAX 请求尽可能异步而不是同步,尤其是在循环中

  2. 替代黑客 - 使用HTML5 WebWorkers,但最好先使用WebWorker 检测来查看您的浏览器是否支持它们,如果不支持,则使用像这样这样的 WebWorker shim 库

  3. 平庸的 hack - setTimeout使用真正的脚本执行计时器并将循环分解为迭代,可能会出现导致更严重问题的边缘情况......

  4. 可怕的黑客 - ActiveX 注册表写入,更好地使用适当的浏览器检测功能检测

  5. 最佳解决方法 - Microsoft FixIT 补丁,如果它只是一小部分用户,请让技术支持将他们发送到官方 Microsoft FixIT 页面(或自己做),这样可以更可靠地添加适当的注册表项以增加脚本执行次数

回答by des

To remove the warning:

要删除警告:

function setMaxScriptStatements(){

var WshShell = new ActiveXObject("WScript.Shell");
    WshShell.RegWrite ("HKCU\Software\Microsoft\Internet Explorer\Styles\MaxScriptStatements", 1107296255, "REG_DWORD");
}

回答by keymone

you can try few things:

你可以尝试一些事情:

  1. running function asynchronously using setTimeout
  2. making your function sleep every now and then to stop blocking UI for long time(hell if it's that slow, let it run a bit longer)
  3. use javascript workers as alternative to setTimeout, here's some quick googling for you: http://ejohn.org/blog/web-workers/
  1. 使用 setTimeout 异步运行函数
  2. 让你的函数不时休眠以长时间停止阻塞 UI(地狱如果它那么慢,让它运行更长时间)
  3. 使用 javascript workers 作为 setTimeout 的替代方法,这里有一些快速的谷歌搜索:http: //ejohn.org/blog/web-workers/