讀完一遍後,有一點沒理解:為什麼在執行這句的時候,會追加一個event callback到隊尾。
[javascript]
status.innerText = 'doing...please wait...';
即原文所謂“由於涉及DOM更新,由DOM Change Event觸發另一個線程,所以排到隊尾”。
因此先複習了一遍C#的事件委託機制,希望從C#優雅簡潔的文法中鞏固基礎、尋找突破。
有點基礎的可以直接從Explanation這一節開始看。
小結如下:
在C#的文法中,delegate(委託)是一個關鍵字,類似於class負責定義類,它負責定義委託類型。
委託類型一般命名為XxxEventHandler,暗示處理某類事件的人。
它的用途僅僅是聲明一個方法簽名,所有符合這個方法簽名的方法,都可以掛載到該委託類型的某個執行個體,即event(事件)上。
如click,doubleClick,KeyPress等,對於這些不同的事件,只要處理的方法簽名一致,可以共用一種委託類型。
掛載的目的是當觸發該事件時就會逐一觸發所有已掛載的方法,以完成事件回調機制。
可以形象地理解成n個人訂報,掛載的動作就是訂閱某個報刊。以後每當該報刊派發,所有訂閱的人都會收到。
所謂訂閱者、觀察者、監聽者都是在描述類似的意思,即事件被觸發後,所有訂閱/監聽/觀察該事件的對象都能收到通知,以便各自執行不同回調動作。
事件對應的被觸發方法,一般命名為onXxxEvent(),如onClick()。其實現即觸發該事件上掛載的所有方法。
事件上掛載的每一個方法,一般來各個XxxListener。
接下來回到javascript的世界:
[javascript]
status.innerText = 'doing...please wait...';
這一句,實際上已經將dom(或者說html)的內容變更了, 緊接著系統會觸發dom changed事件,即逐一回調所有掛載在該事件上的各個方法。
因為事件回調本來就是非同步,數量亦不可知(取決於運行時有多少對象監聽/訂閱了這個事件),因此無需立即同步執行,而只是簡單地把每個方法追加到隊列中。
而其中至少有一個回調是GUI渲染線程負責的repaint動作。
這就是為什麼執行完這一句,排了個event callback到隊尾的原因。
我覺得正確的表述應該是“由於DOM Change Event被觸發,產生一組非同步回調,因此每個回調方法都被追加到隊列中,而其中必然包括GUI渲染線程負責的repaint方法。”
btw,handler的意思有“著手處理事情的人、馴獸(狗)員、(拳擊)教練、經理”,此處可以理解成著手處理事件的對象。
handle才有“把手、手柄,處理”的意思,因此有些地方把handler翻譯成“控制代碼”感覺不恰當,不過似乎也沒有更精鍊更貼切的表達。