成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

簡(jiǎn)要總結(jié)microtask和macrotask

yexiaobai / 1072人閱讀

摘要:眾所周知和都屬于上述異步任務(wù)的一種那到底為什么和會(huì)有順序之分這就是我想分析總結(jié)的問(wèn)題所在了和的作用是為了讓瀏覽器能夠從內(nèi)部獲取的內(nèi)容并確保執(zhí)行棧能夠順序進(jìn)行。只要執(zhí)行棧沒(méi)有其他在執(zhí)行,在每個(gè)結(jié)束時(shí),隊(duì)列就會(huì)在回調(diào)后處理。

前言

我是在做前端面試題中看到了setTimeout和Promise的比較,然后第一次看到了microtask和macrotask的概念,在閱讀了一些文章之后發(fā)現(xiàn)沒(méi)有一個(gè)比較全面易懂的文章,所以我嘗試做一個(gè)梳理性的總結(jié).

這道經(jīng)典的面試題引起了我的興趣
console.log("script start");

setTimeout(function() {
  console.log("setTimeout");
}, 0);

Promise.resolve().then(function() {
  console.log("promise1");
}).then(function() {
  console.log("promise2");
});

console.log("script end");
JavaScript的事件循環(huán)機(jī)制

首先我們先弄清楚setTimeout和Promise的共同點(diǎn),也就是我第一次的看到那道面試題的疑惑點(diǎn).

JavaScript 主線(xiàn)程擁有一個(gè) 執(zhí)行棧 以及一個(gè) 任務(wù)隊(duì)列,主線(xiàn)程會(huì)依次執(zhí)行代碼,當(dāng)遇到函數(shù)時(shí),會(huì)先將函數(shù) 入棧,函數(shù)運(yùn)行完畢后再將該函數(shù) 出棧,直到所有代碼執(zhí)行完畢。

上面的例子的執(zhí)行棧執(zhí)行順序應(yīng)該是這樣的

console.log("script start");
console.log("script end");
Promise.resolve();

而任務(wù)隊(duì)列的執(zhí)行順序應(yīng)該是這樣的

Promise.then(function() {
  console.log("promise1");
});
Promise.then(function() {
  console.log("promise2");
});
setTimeout(function() {
  console.log("setTimeout");
}, 0);

而主線(xiàn)程則會(huì)在 清空當(dāng)前執(zhí)行棧后,按照先入先出的順序讀取任務(wù)隊(duì)列里面的任務(wù)。

眾所周知setTimeout和Promise.then()都屬于上述異步任務(wù)的一種,那到底為什么setTimeout和Promise.then()會(huì)有順序之分,這就是我想分析總結(jié)的問(wèn)題所在了.

macrotasks(tasks) 和 microtasks tasks

tasks的作用是為了讓瀏覽器能夠從內(nèi)部獲取javascript / dom的內(nèi)容并確保執(zhí)行棧能夠順序進(jìn)行。

tasks的調(diào)度是隨處可見(jiàn)的,例如解析HTML,獲得鼠標(biāo)點(diǎn)擊的事件回調(diào)等等,在這個(gè)例子中,我們所迷惑的setTimeout也是一個(gè)tasks.

microtasks

microtasks通常用于在當(dāng)前正在執(zhí)行的腳本之后直接發(fā)生的事情,比如對(duì)一系列的行為做出反應(yīng),或者做出一些異步的任務(wù),而不需要新建一個(gè)全新的tasks。

只要執(zhí)行棧沒(méi)有其他javascript在執(zhí)行,在每個(gè)tasks結(jié)束時(shí),microtasks隊(duì)列就會(huì)在回調(diào)后處理。在microtasks期間排隊(duì)的任何其他microtasks將被添加到這個(gè)隊(duì)列的末尾并進(jìn)行處理。

microtasks包括mutation observer callbacks,就像上例中的promise callbacks一樣。

所以上面的例子執(zhí)行順序的實(shí)質(zhì)是

tasks =>start end以及resolve

microtasks =>promise1和promise2

tasks =>setTimeout

具體應(yīng)用

需要注意的是,在兩個(gè)tasks之間,瀏覽器會(huì)重新渲染。這也是我們需要了解tasks和microtasks的一個(gè)非常重要的原因.

Vue 中如何使用 MutationObserver 做批量處理? - 顧軼靈的回答 - 知乎

根據(jù) HTML Standard,在每個(gè) task 運(yùn)行完以后,UI 都會(huì)重渲染,那么在 microtask 中就完成數(shù)據(jù)更新,當(dāng)前 task 結(jié)束就可以得到最新的 UI 了。反之如果新建一個(gè) task 來(lái)做數(shù)據(jù)更新,那么渲染就會(huì)進(jìn)行兩次。

瀏覽器兼容問(wèn)題

在__Microsoft Edge__, Firefox 40__, __iOS Safari 以及 desktop Safari 8.0.8 中setTimeout會(huì)先于Promise

該例子來(lái)自Jake Archibald-->Tasks, microtasks, queues and schedules,其中有動(dòng)畫(huà)來(lái)展現(xiàn)tasks和microtasks的具體工作流程,十分推薦閱讀
//html
// Let"s get hold of those elements
var outer = document.querySelector(".outer");
var inner = document.querySelector(".inner");

// Let"s listen for attribute changes on the
// outer element
new MutationObserver(function() {
  console.log("mutate");
}).observe(outer, {
  attributes: true
});

// Here"s a click listener…
function onClick() {
  console.log("click");

  setTimeout(function() {
    console.log("timeout");
  }, 0);

  Promise.resolve().then(function() {
    console.log("promise");
  });

  outer.setAttribute("data-random", Math.random());
}

// …which we"ll attach to both elements
inner.addEventListener("click", onClick);
outer.addEventListener("click", onClick);

在這個(gè)例子中,不同瀏覽器的log是不同的,如下所示

Chrome Firefox Safari edge
click click click click
promise mutate mutate click
mutate click click mutate
click mutate mutate timeout
promise timeout promise promise
mutate promise promise timeout
timeout promise timeout promise
timeout timeout timeout

事實(shí)上Chrome是正確的,而且由此可發(fā)現(xiàn)microtasks并不是在tasks的結(jié)束階段開(kāi)始執(zhí)行,而是在tasks中回調(diào)結(jié)束之后(只要沒(méi)有正在執(zhí)行的JavaScript代碼)

總結(jié)

tasks會(huì)順序執(zhí)行,瀏覽器會(huì)在執(zhí)行間隔重新渲染

microtasks會(huì)順序執(zhí)行,執(zhí)行時(shí)機(jī)為

在沒(méi)有JavaScript代碼執(zhí)行的callback之后

在每一個(gè)tasks之后

由于我是前端初學(xué)者,對(duì)于JavaScript還很不熟悉,對(duì)事件循環(huán)的進(jìn)程模型不是很了解,希望這篇文章能夠幫助大家.

事件循環(huán)機(jī)制建議參考文章

阮一峰-->JavaScript 運(yùn)行機(jī)制詳解:再談Event Loop

HTML Living Standard — Last Updated 9 April 2018

tasks建議參考文章

Jake Archibald-->Tasks, microtasks, queues and schedules

理解 JavaScript 中的 macrotask 和 microtask

setImmediate.js --A YuzuJS production

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107676.html

相關(guān)文章

  • 淺析 JS 事件循環(huán)之 Microtask Macrotask

    摘要:常見(jiàn)應(yīng)用則是為了完成一些更新應(yīng)用程序狀態(tài)的較小的任務(wù),如處理的回調(diào)和的修改,以便讓這些任務(wù)在瀏覽器重新渲染之前執(zhí)行。常見(jiàn)應(yīng)用執(zhí)行順序的實(shí)現(xiàn)需要至少一個(gè)和至少一個(gè)。 簡(jiǎn)介 我們?cè)谏弦黄?《淺析 JS 中的EventLoop 事件循環(huán)》 中提到一個(gè) Event Queue,其實(shí)在事件循環(huán)中 queue 一共有兩種,還有一種叫 Job Queue 其中 Event Queue 在 HTML...

    sihai 評(píng)論0 收藏0
  • 理解javascript中的事件循環(huán)(Event Loop)

    摘要:主線(xiàn)程會(huì)暫時(shí)存儲(chǔ)等異步操作,直接向下執(zhí)行,當(dāng)某個(gè)異步事件觸發(fā)時(shí),再通知主線(xiàn)程執(zhí)行相應(yīng)的回調(diào)函數(shù),通過(guò)這種機(jī)制,避免了單線(xiàn)程中異步操作耗時(shí)對(duì)后續(xù)任務(wù)的影響。 背景 在研究js的異步的實(shí)現(xiàn)方式的時(shí)候,發(fā)現(xiàn)了JavaScript 中的 macrotask 和 microtask 的概念。在查閱了一番資料之后,對(duì)其中的執(zhí)行機(jī)制有所了解,下面整理出來(lái),希望可以幫助更多人。 先了解一下js的任務(wù)執(zhí)...

    mykurisu 評(píng)論0 收藏0
  • 瀏覽器環(huán)境下的microtaksmacrotasks

    摘要:的回調(diào)函數(shù)正是處于隊(duì)列之中。將看做會(huì)導(dǎo)致性能問(wèn)題,回調(diào)函數(shù)可能會(huì)因?yàn)殇秩镜认嚓P(guān)產(chǎn)生不必要的延后。瀏覽器是怎么出錯(cuò)的和在兩次點(diǎn)擊操作之間運(yùn)行完成了所有的,就比如的回調(diào)函數(shù)所展示的,但是似乎有不同的排序算法。 帶有可視代碼執(zhí)行順序的原文鏈接https://jakearchibald.com/201...,此篇文字并非其完整翻譯,加入了一部分自己的理解,比如將其中的task替換為macrot...

    econi 評(píng)論0 收藏0
  • 瀏覽器環(huán)境下的microtaksmacrotasks

    摘要:的回調(diào)函數(shù)正是處于隊(duì)列之中。將看做會(huì)導(dǎo)致性能問(wèn)題,回調(diào)函數(shù)可能會(huì)因?yàn)殇秩镜认嚓P(guān)產(chǎn)生不必要的延后。瀏覽器是怎么出錯(cuò)的和在兩次點(diǎn)擊操作之間運(yùn)行完成了所有的,就比如的回調(diào)函數(shù)所展示的,但是似乎有不同的排序算法。 帶有可視代碼執(zhí)行順序的原文鏈接https://jakearchibald.com/201...,此篇文字并非其完整翻譯,加入了一部分自己的理解,比如將其中的task替換為macrot...

    FreeZinG 評(píng)論0 收藏0
  • 帶你徹底弄懂Event Loop

    前言 我在學(xué)習(xí)瀏覽器和NodeJS的Event Loop時(shí)看了大量的文章,那些文章都寫(xiě)的很好,但是往往是每篇文章有那么幾個(gè)關(guān)鍵的點(diǎn),很多篇文章湊在一起綜合來(lái)看,才可以對(duì)這些概念有較為深入的理解。 于是,我在看了大量文章之后,想要寫(xiě)這么一篇博客,不采用官方的描述,結(jié)合自己的理解以及示例代碼,用最通俗的語(yǔ)言表達(dá)出來(lái)。希望大家可以通過(guò)這篇文章,了解到Event Loop到底是一種什么機(jī)制,瀏覽器和Nod...

    hersion 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<