在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)再愈。在修改數(shù)據(jù)之后立即使用這個方法,獲取更新后的 DOM【因為數(shù)據(jù)更新不會立即觸發(fā)Dom變化從而視圖更新---異步渲染滴】
補充: JS 運行機制【http://www.reibang.com/p/f3062be1b430】
(1)所有同步任務都在主線程上執(zhí)行纪岁,形成一個執(zhí)行棧(execution context stack)与柑。
(2)主線程之外伦乔,還存在一個"任務隊列"(task queue)。只要異步任務有了運行結(jié)果垄提,就在"任務隊列"之中放置一個事件榔袋。
(3)一旦"執(zhí)行棧"中的所有同步任務執(zhí)行完畢,系統(tǒng)就會讀取"任務隊列"铡俐,看看里面有哪些事件凰兑。那些對應的異步任務,于是結(jié)束等待狀態(tài)审丘,進入執(zhí)行棧吏够,開始執(zhí)行。
(4)主線程不斷重復上面的第三步。
在瀏覽器環(huán)境中稿饰,常見的 macro task 有 setTimeout锦秒、MessageChannel、postMessage喉镰、setImmediate旅择;常見的 micro task 有 MutationObsever 和 Promise.then
源碼實現(xiàn):
申明了 microTimerFunc 和 macroTimerFunc 2 個變量,它們分別對應的是 micro task 的函數(shù)和 macro task 的函數(shù)侣姆。對于 macro task 的實現(xiàn)生真,優(yōu)先檢測是否支持原生 setImmediate,這是一個高版本 IE 和 Edge 才支持的特性捺宗,不支持的話再去檢測是否支持原生的 MessageChannel柱蟀,如果也不支持的話就會降級為 setTimeout 0;而對于 micro task 的實現(xiàn)蚜厉,則檢測瀏覽器是否原生支持 Promise长已,不支持的話直接指向 macro task 的實現(xiàn)。
這里使用 callbacks 而不是直接在 nextTick 中執(zhí)行回調(diào)函數(shù)的原因是保證在同一個 tick 內(nèi)多次執(zhí)行 nextTick昼牛,不會開啟多個異步任務术瓮,而把這些異步任務都壓成一個同步任務,在下一個 tick 執(zhí)行完畢贰健。
eg