最近在项目中,某些页面需要一直向服务器发送请求,获取最新的数据展示在页面,实现方式是通过setInterval实现的,但是在使用了一段时间之后,浏览器偶然就会报出“运行的脚本造成ie运行速度减慢,是否要停止运行此脚本”之类的提示。网上查了下,当浏览器认为当前运行的脚本处于失控状态的时候,就会给出类似的提示,但是各家浏览器判断脚本失控的原则各不相同。
IE:通过js引擎运行的脚本数量决定,当运行脚本的行数大于500万行的时候,ie就会给出提示,当然,这不是必然的,这有赖于ie对于失控脚本的检查频率。
其他的浏览器,多是通过一段脚本运行的时间判断脚本是否失控,关于这方面详细的内容,可以参考这篇文章。
http://www.cnblogs.com/yuzhongwusan/archive/2012/06/07/2540952.html
知道了提示出现的原因,如何解决呢,前台不断的向后台发送请求,请求回来的数据又经过处理展现,这些都是需要javascript脚本来执行的,不断循环下去,总有一个时刻,代码量积攒达到500万行。但是只要我们能够将IE对代码行数的计数器重置,理论上就永远不会达到代码行数的上限。
有两种方式可以达到上述目的:
- setTimeout
使用setTimeout将要执行的方法包起来,每次循环的时候,调用setTimeout都会采用一个新的计数器,这样理论上应该能减少每个计数器的代码行数总量。
2. 采用事件机制
要执行的代码通过事件来触发,可以通过手动或者自动的click之类解决。事件机制为什么能解决这个问题,是因为IE的代码计数器对事件处理函数里面的代码重新计数,已经跟当前控制流的代码计数器分开了。
考虑到目前我的代码是在不断的循环请求执行,使用setTimeout更加方便,故对setTimeout的处理方式进行了测试。
打印的数字为:<span id="test"></span> <script> var count = jQuery("#test"); for(var j=0;j<1930000;j++){ if(j%10000 == 0){ count.text(j); } } /*在ie浏览器中,如果下方代码去掉setTimeout,则会报脚本失控的提示,加上之后,即不报。但是,即使加了setTimeout,下方的代码循环的次数也远远达不到上方循环的次数,测试时发现,下方循环9000次还正常,改成10000次,又会报脚本失控。 */ //setTimeout(function(){ for(var j=0;j<9000;j++){ if(j%100 == 0){ count.text(j); } } //},1); </script>
经过测试,setTimeout似乎是对ie的代码计数行数产生了影响,但是并未像我预期的那样,行数重置后,又可以循环将近200万次,具体原因还不清楚。