Javascript 如何防止“脚本速度慢”警告,并强制浏览器继续运行脚本,直到它';结束了吗?

Javascript 如何防止“脚本速度慢”警告,并强制浏览器继续运行脚本,直到它';结束了吗?,javascript,Javascript,更新(2013年7月5日): 自从我最初提出这个问题以来,我学到了很多。在下面的一条评论中,有人建议我重新处理这个任务,并找到一种方法来解决它,而不会有阻塞UI的风险。我说这是不可能的,函数必须按原样运行。我真的不记得我试图用这个函数实现什么,但我确信评论者是对的,而我错了。如果你偶然发现这个问题,并处于与我相似的情况,那么非常认真地考虑你的方法是有缺陷的。 你可能还想调查一下 原始问题: 我不会过于具体地讨论我的问题,我会保持这个通用性,这样其他偶然发现这个问题的人会发现它很有用 我有一个

更新(2013年7月5日):

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


原始问题:

我不会过于具体地讨论我的问题,我会保持这个通用性,这样其他偶然发现这个问题的人会发现它很有用

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

我想阻止这种情况发生,这样脚本就可以继续到它的终点

如何做到这一点

一个旁注:如果我能让这个工作,我还想让一个状态栏,类似于你在加载gmail时看到的,出现这样的用户知道事情正在发生


谢谢

您可以尝试不完全阻塞UI,并使用
setTimeout
使其在“另一个线程”中运行

window.setTimeout(function() { ... code ... }, 0);
我之所以说“在另一个线程中”,是因为JS中没有真正的多线程,这是一篇关于它的好文章


编辑:(使此答案更符合web技术的最新情况)


您还可以使用,具体取决于

您可以尝试以下几项:

  • 使用setTimeout异步运行函数
  • 让你的函数时不时地休眠,以避免长时间阻塞UI(该死,如果它那么慢,让它运行更长一点)
  • 使用javascript workers作为setTimeout的替代方法,这里有一些快速的谷歌搜索:

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

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

    var序列=['foo'、'bar'、'baz'、'base'、'ball'、'hello'、'world'、'100k more'],
    开始=日期。现在();
    setTimeout(函数_worker(){
    做{
    var元素=sequence.shift();
    //用元素做些什么
    }while(sequence.length&(Date.now()-start<100));
    if(sequence.length)
    setTimeout(_-worker,25);
    }, 25);
    
    要删除警告,请执行以下操作:

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

    除非您的代码真的非常糟糕或恶意,否则这种情况几乎总是只发生在IE 9及以下版本中,当无辜脚本的循环执行时间太长,或者对速度较慢的服务器进行AJAX调用,或者需要返回大量数据,并且超出了允许的限制时

    因此,如果您的用户确实感到困扰,您可以在此处让他们遵循Microsoft的官方解决方案: 如果他们运行Microsoft FixIT修补程序,将默认的MaxScriptStatements从默认的5000000语句增加到允许的最大值(用十六进制值0xFFFFFF表示,它等于4294967295个执行语句总数),则应能解决问题,除非我提到,代码特别糟糕,或者需要重构

    总之,您的选择是:

  • 最佳解决方案-。。。在N次执行之后,分解循环和/或停止递归,并确保AJAX请求尽可能地满足要求,特别是在循环中

  • 替代黑客-使用,但最好先使用查看是否支持它们,如果不支持,则使用WebWorker shim库

  • 平庸的黑客-具有真实的循环并将循环分解为迭代,可能会出现导致更严重问题的边缘情况

  • 可怕的黑客-,最好使用适当的plus

  • 最佳解决方案—,如果只是一小部分用户,请技术支持部门将他们发送到官方的Microsoft FixIT页面(或自己动手),该页面可以更可靠地添加适当的注册表项以增加脚本执行计数


  • 我认为你需要修复你的函数,这样就不会花那么长时间。然后你需要在浏览器之外的其他地方进行修复。也许你可以把这个函数移植到你正在使用的任何服务器端语言上。我先试试felipe的建议,如果必须的话,我会把它传递给服务器。谢谢你的提示。所以我现在使用for循环来解析字符串中的每个字符。我将用一个手动计数器和一个setTimeout来代替它,看看会发生什么。等待这就是你的建议吗?你只需要在做这件事时小心范围问题:)毫无疑问。谢谢你的帮助。我会告诉你发生了什么。这有助于防止慢速脚本警告。它还允许我添加一个进度条。setInterval比传统的forloop慢得多,尽管这样做不值得。
    function setMaxScriptStatements(){
    
    var WshShell = new ActiveXObject("WScript.Shell");
        WshShell.RegWrite ("HKCU\\Software\\Microsoft\\Internet Explorer\\Styles\\MaxScriptStatements", 1107296255, "REG_DWORD");
    }