2011-06-07 75 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