2011-06-07 71 views
16

我正在考虑在我们的JavaScript实用程序断言函数中添加alert()。js:了解alert()如何影响浏览器事件循环

我们是一个ajax沉重的应用程序,我们的框架(Ext)通过使用setInterval轮询ajax响应而不是等待readystate == 4来实现ajax,这会导致我们所有的ajax回调在setInterval堆栈上下文 - 并且一个异常/断言通常会失败。

低级alert()如何影响浏览器事件循环?根据定义,消息框必须允许win32事件循环进行抽取(以响应mbox按钮)。这是否意味着其他浏览器事件,比如由我们的框架生成的未来setIntervals,调整事件大小等,是否会触发?这会对我造成麻烦吗?

IIRC:您可以使用FF2和FF3.5来查看我正在谈论的差异。

alert('1'); 
setTimeout(function(){alert('2');}, 10); 
alert('3'); 

FF 3.5显示1-3-2。 FF2 [1]显示1-2(其中2和3同时堆叠在彼此之上)。我们可以在IE8中复制1-2 & 3,同时从activex启动win32 mbox,而不是在当天发出havok的警报,我想确保我们不会再次沿着这条路走下去。

任何人都可以向我指出解释此行为的具体低级资源,此处预期的行为以及低级别发生了什么,包括为何行为在FF版本中发生更改?

[1]你可以在Spoon.net上复制这个,我现在无法工作。我刚刚用FF 2.0.0.20在vm上重新编译了它。

+0

优秀的问题。根据我的经验,“alert”的实现在不同浏览器上有很大不同。一般来说,我会避免使用自定义(即jQuery UI风格)对话框的“alert”。 – 2011-06-07 17:19:12

+0

@Oliver - 是的,我们实际上选择使用基于DOM的弹出窗口,但我仍然想要了解警报内部。 – 2011-06-07 18:56:38

+1

*“根据定义,消息箱必须允许win32事件循环泵”* - 某些操作系统 - 例如Mac OS X - 使用嵌套的事件循环。警报可能会运行阻塞主事件循环的[模式事件循环](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/WinPanel/Concepts/UsingModalWindows.html)。有些浏览器可能会为对话框做类似的事情。 – s4y 2011-06-08 21:10:58

回答

1

我还没有能够复制1-2个案例,但here是一个小工具,它可以帮助您调试不同浏览器中正在进行的操作。

+0

真棒工具,谢谢 – 2011-06-07 17:32:14

+0

@Dustin Getz没问题,希望它有帮助! – Briguy37 2011-06-07 17:37:45

7

首先,javascript中的定时器不是很精确。小于30ms的间隔可能会被视为完全相同,并且实现方式也会有所不同。不要依赖任何隐式排序。

alert()将始终停止事件循环。如果事件或定时器在警报期间触发,则在事件循环恢复后(警报框关闭),它们将排队并调用。

拿这个例子:

var hello = document.getElementById('hello') 

setTimeout(function(){ 
    hello.style.backgroundColor = 'lime' 
}, 5000) 

alert('Stop!') 

setTimeout(function(){ 
    hello.innerHTML = 'collaborate' 
}, 20) 

setTimeout(function(){ 
    hello.innerHTML = 'listen' 
}, 1000) 

有两种可能的结果:

  1. 您关闭该警告框下5秒。随后的两个定时器将按指定的时间间隔设置并触发。您可以看到事件循环已停止,因为无论等待关闭警报多久,“侦听”将始终执行1秒。

  2. 您需要花费超过5秒的时间来关闭警报。第一个间隔(bgColor)将会通过,所以它立即执行,然后两个定时器被设置和调用。

http://jsbin.com/iheyi4/edit

至于间隔,而事件循环停止它也是在这种情况下,“停止时间”,所以:

i = 0 

setInterval(function(){ 
    document.getElementById('n').innerHTML = ++i 
}, 1000) 

setTimeout(function(){ 
    alert('stop') 
}, 5500) 

不管你需要多长时间才能关闭警报,下一个数字将始终为6 - setInterval不会多次触发。

http://jsbin.com/urizo6/edit

+0

好点。 'alert()将永远停止事件循环 - 至少,浏览器进程的win32消息泵正在处理wm_paint,因为如果我们移动mbox,它会重新绘制。在FF3 +中setInterval等待是因为wm_timer没有处理,还是因为与javascript vm的一些奇特交互? – 2011-06-08 20:52:22

+0

@Dustin:javascript事件循环显然不同于win32事件队列(在win32中没有隐式循环)。我非常确定WM_TIMER一直处于正常状态,只有javscript超时的实现方式才会显得不同。 – 2011-06-08 21:11:22