這是一則面試題,請不要考慮實務上出現的合理性題目是
- 點擊按鈕後會不會發生效果
- 為什麼會 or 不會
See the Pen
macrotask & microtask by Dean (@hcd1983)
on CodePen.0
和瀏覽器的渲染流程相關 (目前我測試了最新版的 chrome, firefox, edge 都適用)
如下圖的 function
1. 首先要理解 macrotask 和 microtask 在事件發生的執行順序,非同步事件拉到所有同步事件的最後 (setTimeOut, async…) 執行,通常瀏覽器的設計會在 microtask 結束後再做 render (repaint / reflow) 以免改變的外觀次數太頻繁,消耗資源。
2. microtask 通常由 Promise 觸發,是一個專門 callback 的特殊 api 會在事件的結尾執行。因此在下圖 function 的執行順序如下: alert => changeText => Promise (loopForever) => changeColor (setTimeout)
3. 執行後 alert 順利出現,其他卻好像無反應。以下一一探究:changeColor (setTimeout) 因為被拉到 macrotask 的最後面,所以在等待 microtask 執行完畢,因為 Promise 的無限迴圈被擋掉,完全不會觸發。changeText 有被觸發嗎? 有,而且 dom 的屬性被改變了。但是因為 Promise 的無限迴圈還在跑,所以瀏覽器一直不 render 。
4.最後會發生電腦猶如哀嚎的運轉聲,瀏覽器跳出錯誤警示,是由於無限 loop 造成的系統過載。