[譯] 事件迴圈中microtask和macrotask的不同之處

DuKe發表於2019-03-03

stackoverflow地址: Difference between microtask and macrotask within an event loop context

問:

我剛剛讀完了Promises/A+規範,但被microtask 和 macrotask這兩個名詞給困擾到了: 詳情見promisesaplus.com/#notes

我之前從來沒聽過這些名詞,現在我很好奇它們之間到底有什麼區別?

我已經盡我所能的在網上搜羅了一些資訊,但只找到了w3.org歸檔中的一篇文章(但裡面沒有解釋倆名詞之間的不同點):lists.w3.org/Archives/Pu…

另外,我發現了一個npm模組,名字就叫做”macrotask”: www.npmjs.org/package/mac… .但可惜的是,它並沒有說清楚不同之處到底是什麼.

我所能瞭解到的只是,它們與事件迴圈有關,如html.spec.whatwg.org/multipage/w…html.spec.whatwg.org/multipage/w…中所述.

我知道我理論上能通過WHATWG規範憑自己找到它們的不同點.但我確信假如有這方面的專家能給出一個簡短的解釋,那麼其他人肯定也會從中受益良多.

高票回答1:

一輪事件迴圈將只會精確的執行一個來自macrotask佇列的任務(這個佇列在[WHATWG 規範]中被簡稱為task 佇列(html.spec.whatwg.org/multipage/w…)).

當該macrotask完成後,所有可用的microtasks都將被執行,即在同一輪迴圈內.當這些microtasks都被處理完後,它們可能會將更多的microtasks加入到佇列中去,這些任務將會依次執行,直到microtask佇列為空.

那麼這種情況的實際結果到底是什麼樣呢?

如果一個microtask遞迴地將其它microtasks加入佇列,這將會導致下一個macrotask需要等待很久才能執行.這意味著,你的程式可能會因為一個被阻塞的UI或者一些已完成但空置的I/O被告以結束.

但是,至少Node.js的process.nextTick函式(負責對microtasks進行排隊),有一套內建的保護機制,可以通過設定process.maxTickDepth來防止類似的阻塞行為.該值預設為1000,一旦到達該值,那麼超出該限制外的一切microtasks處理行為將會被切斷,這樣就可以處理下一個macrotask了.

所以何時使用它們?

通常,當你需要以同步的方式做一些非同步的事情時(i.e. 當你想在一旦完成該(micro-)task就執行某些程式碼的時候).

否則的話,繼續使用macrotasks.

具體分類:
macrotasks: setTimeout, setInterval, setImmediate, I/O, UI 渲染

microtasks: process.nextTick, Promises(注:瀏覽器原生Promise), Object.observe, MutationObserver

相關文章