什么算作IE的"停止运行此脚本?"的"执行脚本声明"?警告柜台?

use*_*ca8 5 javascript internet-explorer

在一个同步脚本执行中(例如,从超时或事件处理程序)发生5,000,000 "执行脚本语句"时, Internet Explorer 8(我需要支持,不可协商)显示以下警告.

停止运行此脚本?此页面上的脚本导致Web浏览器运行缓慢.如果它继续运行,您的计算机可能会无响应.

我正在尝试优化一些复杂的重载代码以避免此错误消息.我已经遵循了标准建议,即在可能的情况下使用类似的东西将代码分成单独的异步块setTimeout().在没有创建竞争条件的情况下,我无法做更多这样的事情,因此我希望简化所有多次发生的代码,例如在大for循环中.

要做到这一点,我想了解IE究竟是什么算作"执行脚本语句",所以我将知道我的循环中哪些优化会产生最大的差异,哪些优化不会.

我已经找到了"执行脚本语句"的标准定义,但没有成功 - 大多数时候使用"脚本语句",它似乎是指html <script>标签的内容,这显然是一个不同的术语.声明(计算机科学)的定义很有帮助,但是对它们的计算方式却有些模棱两可(见下面的例子).

以下是微软就此事发表的意见(为了便于阅读,我添加了分节符):

从Internet Explorer 4.0及更高版本开始,超时不再是基于Windows消息的固定值.Internet Explorer现在跟踪已执行的脚本语句的总数,并在每次启动新脚本时重置该值,例如从超时或事件处理程序,对于具有脚本引擎的当前页面.

当该值超过阈值量时,Internet Explorer将显示"长时间运行的脚本"对话框.

Internet Explorer不检查每条指令是否超出限制.脚本引擎会定期轮询Internet Explorer,其中包含执行的语句数,Internet Explorer会检查是否超出限制.由于这种机制,如果整个脚本执行在脚本引擎轮询Internet Explorer之前完成,则可以在没有对话框的情况下执行超过默认限制.

给出一些看似含糊不清的简单例子:

  1. var a = 1, b = 2, c = 3;算一个"执行的脚本语句"和var a = 1; var b = 2; var c = 3;算三?或者两者都是三个?
  2. 会不会if( someFunction() ){}(不包括someFunction()一个声明中的声明,或两个声明(一个电话加一个条件)?
  3. if(a){}else{}一个或两个有条件的陈述?如果一个,会if(a){}else if(b){}是两个?
  4. if(a==b||(c&&a==c&&c==d)){}一,二,三,四,五个陈述(或更多?)?我知道任何类似if(a){}调用Javascript函数转换为布尔值的东西 - 这会在比较本身之上添加额外的语句吗?
  5. var value = someFunction(); if( value ){}有三个,因为它增加了一个任务,或将函数调用进行计数作为赋值语句的一部分?
  6. 链接怎么样?例如,如果jQuery是使用,那么(不算执行脚本语句各功能)是行$(selector).show().css(obj).appendTo($el);一个"执行脚本语句",或四个?我想这将是四个"通话"声明.
  7. 据推测,var $someEl = $(selector).show().css(obj).appendTo($el);会增加到五个语句 - 四个调用加一个赋值?(IE不会把它算作一个赋值语句并继续前进吗?)

当然,上面这些简单的例子都是小型的 - 我试图"了解敌人",以便能够判断如何最好地优化复杂的循环.

我正在寻找一个经验法则或一些如上所述的解释例子

jww*_*art 0

据我了解,浏览器从队列中执行代码。

当某些代码正在运行并且您创建了 setTimeout() 时,即使您将超时设置为 4 毫秒(每个浏览器可能不同,下面不注释),该代码也不会与浏览器中的其他 JavaScript 代码并行执行。相反,该函数被放入队列中。

当前执行的脚本完成后,它将在队列中查找下一个要执行的项目。队列可以有事件处理程序(来自用户输入,尽管我认为它们可能是优先级的,不确定)和诸如 Ajax 调用响应之类的东西(如 jQuery ajax 调用成功代码等),它们都被添加到队列中并被执行一个一次。

JavaScript 总是在单个线程中运行,从来没有两个线程并行运行 JavaScript 代码。该线程从队列中挑选内容并一次执行一个。

注意:您最好不要在大 for 循环中运行,因为这会触发您遇到的错误。