更新(2013年7月5日):
自从我最初提出这个问题以来,我学到了很多东西。在下面的一条评论中,有人建议我重新处理任务并找到解决问题的方法,而不会有阻止UI的风险。我说这是不可能的,函数必须按原样运行。我实际上并不记得我试图通过该功能完成的任务,但我确信评论者是对的,我错了。如果您偶然发现这个问题并且处于与我相似的情况,那么请认真考虑您的方法存在缺陷的可能性。
您可能还想查看web workers。
Here is where you can expect them to work.
原始问题:
我不会过分具体地解决我的问题,而是保持这种通用性,以便其他偶然发现它的人可以发现它很有用。
我有一个接受一个参数的函数,一个字符串。如果字符串很短,则函数运行正常并及时完成。但是,如果传入的字符串太长,脚本会运行一段时间,那么最终会超时并返回浏览器的慢脚本对话框,允许用户终止脚本。
我想防止这种情况发生,以便脚本可以继续到它的终点。
如何做到这一点?
旁注:如果我能够正常工作,我还想创建一个状态栏,类似于加载gmail时看到的状态栏,这样用户就知道事情正在发生。
谢谢!
答案 0 :(得分:6)
您可以尝试不要完全阻止用户界面,并使用setTimeout
“在另一个主题中”运行。
window.setTimeout(function() { ... code ... }, 0);
我说“在另一个线程中”因为JS中没有真正的多线程,而here是关于它的好文章
编辑:(使这个答案与网络技术保持同步)
您还可以使用HTML 5 Web Workers ,具体取决于browser you are targeting
答案 1 :(得分:5)
无法通过脚本在任何浏览器中禁用该行为。想象一下影响,禁用该功能并调用while(1)
。非常糟糕。
您可以创建不阻止浏览器“太久”的代码。如果最佳实践模式有一吨。我总是建议尝试将你的algorythm分解成更小的块。将它与失控定时器和循环相结合,确保任何操作的运行时间不超过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);
答案 2 :(得分:3)
除非您的代码确实是恶意或恶意的,否则这几乎总是在IE 9及更低版本中发生,当无辜的脚本具有执行时间太长的循环或者对慢速服务器进行AJAX调用或者有大量数据时退回,超过允许的限制。
因此,如果真的困扰他们,您可以让您的用户在此处关注此问题的Microsoft官方修复: http://support.microsoft.com/kb/175500 如果他们运行此 Microsoft FixIT修补程序,则会将其默认的 MaxScriptStatements 从默认的5,000,000个语句增加到允许的最大值(由十六进制值 0xFFFFFF 表示,这是等于4,294,967,295总执行声明)它应该解决问题,除非我提到,代码特别糟糕或需要重构。
总之,您的选择是:
最佳解决方案 - fix your script ...在N次执行后分解循环和/或停止递归,并确保AJAX请求尽可能asynchronous not synchronous,尤其是在循环中
替代黑客 - 使用 HTML5 WebWorkers ,但最好先使用WebWorker detection查看your browser是否支持它们,并使用类似的WebWorker填充程序库如果不支持,则this或this
平庸的黑客攻击 - setTimeout ,真正的script execution Timer并打破循环迭代,可能会有边缘情况导致更严重的问题......
糟糕的黑客 - ActiveX registry writing ,最好使用正确的browser detection加上feature detection
最佳解决方法 - Microsoft FixIT patch ,如果只是一小部分用户,请将技术支持发送到官方Microsoft FixIT页面(或自己动手)可靠地添加适当的注册表项以增加脚本执行次数
答案 3 :(得分:1)
你可以尝试一些事情:
答案 4 :(得分:1)
删除警告:
function setMaxScriptStatements(){
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.RegWrite ("HKCU\\Software\\Microsoft\\Internet Explorer\\Styles\\MaxScriptStatements", 1107296255, "REG_DWORD");
}