從event loop出發(fā)討論P(yáng)romise到涂、setTimeout的執(zhí)行順序

***

Event Loop 這個(gè)概念相信大家或多或少都了解過,所謂溫故而知新丐吓,so,今天,我們就從event loop出發(fā),看看在事件的執(zhí)行過程中,他都經(jīng)歷了些什么液肌。

#### 什么是event loop

event loop是js的事件執(zhí)行機(jī)制,我們一般簡稱為事件循環(huán)(之所以稱作事件循環(huán)鸥滨,是因?yàn)樗?jīng)常被用于類似如下的方式來實(shí)現(xiàn))

```javascript

while (queue.waitForMessage()) {

? ? ? ? ? ? queue.processNextMessage();

? ? ? ? ? ? }

```

? ? ? 如果當(dāng)前沒有任何消息`queue.waitForMessage` 會(huì)等待同步消息到達(dá),當(dāng)完成當(dāng)前任務(wù)后嗦哆,繼續(xù)去查看有無需要執(zhí)行的任務(wù)如果需要執(zhí)行谤祖,就再次執(zhí)行,如此循環(huán)老速,所以稱之為事件循環(huán)粥喜。

#### 同步和異步任務(wù)

? ? ? 要了解異步線程我們首先應(yīng)該明白它的用處,因?yàn)閖s的`單線程`特性橘券,任務(wù)的執(zhí)行順序都是依次執(zhí)行额湘,而當(dāng)我們在工作中遇到網(wǎng)絡(luò)請求,前后端交互的時(shí)候旁舰,你的數(shù)據(jù)不會(huì)馬上拿到锋华,這需要時(shí)間,如果等拿到數(shù)據(jù)再執(zhí)行下面的代碼箭窜,這樣如果多次請求就會(huì)發(fā)現(xiàn)加載速度極慢毯焕,這樣顯然不合理,這樣就會(huì)出現(xiàn)很多次的暫停等待磺樱,所以這時(shí)候 需要執(zhí)行異步任務(wù)纳猫,當(dāng)我們發(fā)起請求時(shí)候,采用異步的方式坊罢,瀏覽器檢測到其為異步時(shí)续担,就會(huì)開辟一個(gè)新的進(jìn)程處理該函數(shù)擅耽,然后繼續(xù)執(zhí)行后面的任務(wù)活孩,當(dāng)完成了執(zhí)行棧里的同步任務(wù)之后,再檢測是否有異步任務(wù)需要執(zhí)行乖仇,最后執(zhí)行異步任務(wù)憾儒。

```javascript

-同步任務(wù)進(jìn)入主線程,按順序從上而下依次執(zhí)行乃沙,

-異步任務(wù)起趾,進(jìn)入`event table` ,注冊回調(diào)函數(shù) `callback` 警儒,

任務(wù)完成后训裆,將`callback`移入`event queue`中等待主線程調(diào)用

```

#### 異步任務(wù)分為微任務(wù)和宏任務(wù)

? ? ? 在執(zhí)行過程中,我們知道了同步任務(wù)會(huì)優(yōu)先異步任務(wù)執(zhí)行蜀铲,那么在異步中呢边琉,異步中同樣包含微任務(wù)和宏任務(wù),首先我們大概了解下微任務(wù)和宏任務(wù)记劝,在js中:

* 微任務(wù)(micor Task) :promise? MutationObserver process.nextTick

* 宏任務(wù)(macro Task):script settimeout setinterval setImmediate requestAnimationFrame

> 宏任務(wù)

>

> | #? ? ? ? ? ? ? ? ? ? | 瀏覽器 | node |

> | --------------------- | :----: | :--: |

> | I/O? ? ? ? ? ? ? ? ? |? √? ? |? √? |

> | setTimeOut? ? ? ? ? ? |? √? ? |? √? |

> | setInterval? ? ? ? ? |? √? ? |? √? |

> | setImmediate? ? ? ? ? |? ×? ? |? √? |

> | requestAnimationFrame |? √? ? |? ×? |

>

> 微任務(wù)

>

> | #? ? ? ? ? ? ? ? ? ? ? ? ? | 瀏覽器 | node |

> | -------------------------- | :----: | :--: |

> | process.nextTick? ? ? ? ? |? ×? ? |? √? |

> | MutationObserver? ? ? ? ? |? √? ? |? ×? |

> | Promise.then catch finally |? √? ? |? √? |

這兩種任務(wù)在不同環(huán)境下支持的各不同变姨,今天我們主要看看在瀏覽器中,我們經(jīng)常會(huì)遇到的有 `promise` 和 `setTimeout` 我們通過下面這段代碼來看看:

```javascript

? ? console.log(1)


? ? setTimeout(() => console.log(2), 0)


? ? new Promise((resolve, reject) => {

? ? ? ? console.log(3)

? ? ? ? resolve()

? ? }).then(() => {

? ? ? ? console.log(4)

? ? })

```

首先來分析下厌丑,這段代碼中包含同步任務(wù)定欧,包含異步的宏任務(wù)`setTimeout`,包含異步的微任務(wù)`promise`,這套題的答案是1.3.4.2 渔呵,我們首先找到同步任務(wù),1 3 是同步任務(wù)砍鸠,然后執(zhí)行異步任務(wù)扩氢,異步任務(wù)如果按順序執(zhí)行則是24? 但是答案是4.2那么我們可以知道 promise的執(zhí)行順序優(yōu)先于setTimeout所以由此可知,在異步任務(wù)中爷辱,微任務(wù)優(yōu)先于宏任務(wù)執(zhí)行,可以看看下圖类茂。

`紅線就是任務(wù)的執(zhí)行順序`

`黑線是任務(wù)的結(jié)構(gòu)`

看完這么多下面來完成下面這道題并加以分析:

```javascript

console.log(1)

setTimeout(() => {

? ? console.log(2)

? ? new Promise((resolve, reject) => {

? ? ? ? console.log(3)

? ? ? ? resolve()

? ? }).then(() => {

? ? ? ? console.log(4)

? ? })

}, 0)

new Promise((resolve, reject) => {

? ? console.log(5)

? ? resolve()

}).then(() => {

? ? console.log(6)

})

setTimeout(() => {

? ? console.log(7)

? ? new Promise((resolve, reject) => {

? ? ? ? console.log(8)

? ? ? ? resolve()

? ? }).then(() => {

? ? ? ? console.log(9)

? ? })

}, 0)

console.log(10)

const promise = new Promise((resolve, reject) => {

? ? console.log(1);

? ? console.log(2);

? });

? promise.then(() => {

? ? console.log(3);

? });

? console.log(4);

```

> 答案:`1 , 5 , 10 , 6 , 2 , 3 , 4 , 7 , 8 , 9`

? 廢話不多說直接解題

+ 進(jìn)入主線程開始執(zhí)行, 遇到 `console.log(1)`托嚣, 輸出 `1`

+? 遇到一個(gè) `setTimeout` 宏任務(wù)巩检, 將其回調(diào)函數(shù)推入 `macro Task` 的 `event queue` 中,`macro Task` 的 `event queue` 中記一個(gè)任務(wù) `setTimeout1`

+ 然后碰到 `promise` 微任務(wù)示启, 直接執(zhí)行 `new Promise` 輸出 `5`, 并將 `then` 函數(shù)的回調(diào)函數(shù)推入 `micro Task` 的 `event queue` 中, `micro Task` 的 `event queue` 中記 一個(gè) 微任務(wù) `promise1`

+ 又遇到了 `setTimeout` 宏任務(wù)兢哭, 同理,將其回調(diào)函數(shù)推入 `macro Task` 的 `event queue` 中夫嗓,`macro Task` 的 `event queue` 中記一個(gè)任務(wù) `setTimeout2`

+ 最后迟螺,執(zhí)行 `console.log(10)`, 輸出 10

> 上一輪事件循環(huán)結(jié)束,我們發(fā)現(xiàn)舍咖,已經(jīng)輸出 `1 5 10` 了矩父, 按照我們之前所說,這個(gè)時(shí)候排霉,主線程會(huì)去檢查 是否存在微任務(wù)窍株,不難發(fā)現(xiàn),這個(gè)時(shí)候的 `event queue` 是這個(gè)樣子的

| **micro Task (微任務(wù))** | **macro Task(宏任務(wù))** |

| :---------------------: | :--------------------: |

|? ? ? ? promise1? ? ? ? |? ? ? setTimeout1? ? ? |

|? ? ? ? ? ? ? ? ? ? ? ? |? ? ? setTimeout2? ? ? |

```javascript

主線程 ---> promis1 ---> settimeout1 ---> settimeou2 ---> 循環(huán)檢查主線程任務(wù)棧是否還有任務(wù)

```

#### 結(jié)語

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末攻柠,一起剝皮案震驚了整個(gè)濱河市球订,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瑰钮,老刑警劉巖冒滩,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異浪谴,居然都是意外死亡开睡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門苟耻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篇恒,“玉大人,你說我怎么就攤上這事梁呈』槎龋” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蝗茁。 經(jīng)常有香客問我醋虏,道長,這世上最難降的妖魔是什么哮翘? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任颈嚼,我火速辦了婚禮,結(jié)果婚禮上饭寺,老公的妹妹穿的比我還像新娘阻课。我一直安慰自己,他們只是感情好艰匙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布限煞。 她就那樣靜靜地躺著,像睡著了一般员凝。 火紅的嫁衣襯著肌膚如雪署驻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天健霹,我揣著相機(jī)與錄音旺上,去河邊找鬼。 笑死糖埋,一個(gè)胖子當(dāng)著我的面吹牛宣吱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瞳别,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼征候,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了洒试?” 一聲冷哼從身側(cè)響起倍奢,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎垒棋,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痪宰,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叼架,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衣撬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乖订。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖具练,靈堂內(nèi)的尸體忽然破棺而出乍构,到底是詐尸還是另有隱情,我是刑警寧澤扛点,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布哥遮,位于F島的核電站岂丘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏眠饮。R本人自食惡果不足惜奥帘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仪召。 院中可真熱鬧寨蹋,春花似錦、人聲如沸扔茅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽召娜。三九已至评姨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間萤晴,已是汗流浹背吐句。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留店读,地道東北人嗦枢。 一個(gè)月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像屯断,于是被迫代替她去往敵國和親文虏。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容