2012-05-04 293 views
0

我寫一個Firefox擴展,這是做兩件事情(對這個問題的上下文中)訪問的DOM API:在Firefox擴展

  1. 註冊爲某些DOM事件,即DOMContentLoadedDOMFrameContentLoaded
  2. 在回調事件時,訪問DOM API並執行某些操作。

擴展名獲取第一個事件(DOMContentLoadedDOMFrameContentLoaded),並且回調函數調用一些DOM API。我在觀察,在調用從DOM API調用返回到我的擴展之前,另一個事件觸發和我的回調函數被調用(我還沒有能夠縮小哪個特定的DOM API,因爲我的擴展調用了一堆DOM蜜蜂)。

這甚至可能嗎?順便說一句,我在Windows上的Firefox 12上。我正在打印threadManager.isMainThread,並且在這兩種情況下,都會在主線程上調用事件回調。

任何指針將不勝感激。

回答

0

JavaScript通常是單線程的。但是,這並不意味着函數不能重新進入(一個函數本身就是最明顯的例子)。所以當另一個事件處理程序正在執行時,仍然可以調用事件處理程序AFAICT這可能發生在以下情況下:

  • 事件處理程序導致(直接或間接)生成和分派另一個事件。特別是,DOM操作會導致突變事件 - 這些事件的處理是同步發生的。例如。調用element.setAttribute()將創建DOMAttrModified事件,並且該事件將在element.setAttribute()返回之前處理,包括正在運行的事件處理程序。
  • 事件處理程序處於「已暫停」狀態。如果打開一個模式對話框(如alert()),通常會發生這種情況 - 當前事件處理程序將等待此對話框關閉,而其他事件處理程序仍可被觸發。不常見的情況是使用yield keyword in generators
  • 事件處理程序調用nsIThread.processNextEvent()。這個調用可能會執行與隊列中下一個事件關聯的事件處理程序。從技術上講,這一點與之前的相同 - alert()將在內部調用nsIThread.processNextEvent()以確保在呼叫者被阻止時處理事件。
+0

感謝弗拉基米爾答案。我沒有直接做任何你提到的事情。在我的擴展中,我正在註冊DOMContentLoaded和DOMFrameContentLoaded。在我的測試案例中,我看到DOMContentLoaded被解僱,並且在我的處理程序中,我調用了一些DOM API來讀取數據,並在返回之前調用DOMFrameContentloaded。我並不直接導致(至少是直接)導致這些事件在我處理過程中被調用。你知道在返回之前是否有任何DOM API在內部調用processNextEvent()嗎?如果是的話,無論如何要壓制這種行爲? –

+0

不,AFAIK內部調用'processNextEvent()'的唯一東西是模態對話框和同步'XMLHttpRequest'。 –

+0

再次感謝。順便說一句,我正在使用的測試頁有內嵌的Java小程序,可以作爲Firefox內部processNextEvent()的代碼路徑嗎?我可以在Firefox代碼庫中驗證這一點嗎? –