国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

圖解 Node.js 的核心 Event-loop

開發 前端
Node.js 是一個完完全全的消息驅動型模型。Node進程活著的最大意義是:有各種各樣的 Event 以及綁定在 Event 上面的Callback 和Data需要它(main thread 和 worker thread)處理。

這次我們來聊聊 Node.js 里面涉及到的一個核心概念:event-loop 。只有理解了它,才能明白 node 的進程模型,也才能明白異步調用在實現層面是什么樣子的,更能明白當同步代碼和異步代碼混雜在一起的時候,CPU 到底跑到我們代碼的哪一行了。文章分為兩篇:event-loop 篇和 Promise/Generator/async 篇。今天我們關注 event-loop 部分。

1、代碼思考

我寫了兩個函數,函數內部直接用 while(true){} 寫了一段死循環代碼。我們先來思考下面這段 Node.js code 執行結果是什么?很多人說 Node.js 是單線程的。如果是這樣,那 CPU 會不會陷入到 whileLoop_1() 的 while 循環里面出不來?

'use strict';
async function sleep(intervalInMS)
{
return new Promise((resolve,reject)=>{
setTimeout(resolve,intervalInMS);
});
}
async function whileLoop_1(){
while(true){
try {
console.log('new round of whileLoop_1');
await sleep(1000); // LINE-A
} catch (error) {
// ...
}
}
}
async function whileLoop_2(){
while(true){
try {
console.log('new round of whileLoop_2');
await sleep(1000); // LINE-B
} catch (error) {
// ...
}
}
}


whileLoop_1(); // LINE-C
whileLoop_2(); // LINE-D

不賣關子了,我先把執行結果發出來。

new round of whileLoop_1
new round of whileLoop_2
new round of whileLoop_1
new round of whileLoop_2
new round of whileLoop_1
new round of whileLoop_2
new round of whileLoop_1
new round of whileLoop_2
new round of whileLoop_1
new round of whileLoop_2
...

是的,正如你所見。這兩個 while 循環分別在交替執行, CPU 也沒有陷入到死循環里面出不來。那么問題來了:

  • CPU 執行到 LINE-A 的時候發生了什么使得它能成功脫身并有機會執行 whileLoop_2 ?
  • CPU 執行到 LINE-B 后,為什么又能回到 whileLoop_1 中繼續執行呢?

2、event-loop

在回答上面的問題前,我們需要先來看一個至關重要的概念:event-loop 。其實我們平時說 Node.js 是單線程僅僅是指 node 執行我們的 JS 代碼,更準確地說是 V8 執行 JS code 是發生在單線程里面的。實際上如果你打開 node 進程,會發現它有不少 worker thread。這是一個典型的單進程多線程模型。這些 worker thread 被放置于線程池里面,而 V8 執行 JS code 的線程被稱為主線程。主線程和線程池的配合關系如下圖所示。主線程負責執行 JS  code ,線程池里面的 worker thread 負責執行類似訪問 DB、訪問文件這樣的耗時費力的工作,它倆通過消息隊列協調工作。這和餐館工作流程類似。餐館由一個長得漂亮的小姐姐招呼客人落座并負責收集來自各個餐桌的點單。每當收到一個點好的菜單時,小姐姐會迅速地把它通過一個小窗口遞交給后廚。后廚那里有一個小看板,所有的點單都被陳列在看板上。廚師長根據訂單的時間和菜品安排不同的廚師燒菜。菜燒好后,再由小姐姐負責上菜。

圖片

圖 1:Node.js 單進程多線程模型

嗯上面這張圖還是太簡單了,用來騙新手可以,我知道滿足不了你們。我們把它放大一些。下圖中左邊是主線程,右邊是線程池和一個 worker thread,中間是消息隊列。

圖片

圖 2:Node.js 主線程和工作線程關系圖

(1)主線程

主線程只干一件事:拼命地執行 JS code,做 non-blocking I/O 操作。這些 JS code 既包含我們自己寫的,也包含我們所依賴的 npm package 。這里提到的 non-blocking I/O 操作意味著主線程干的事情基本上都是非阻塞型的工作,例如對 2+3 求和,迭代數組等。主線程以 tick 為粒度工作。是的,你一定聽說過 process.nextTick() ,所謂 next tick 就是下一次執行 tick 的時機。每個 tick 又包含若干個 phase ,按照 Node.js 官網介紹,目前為止一共有 6 個 Phase。

  • timers: 這個 phase 執行通過 setTimeout()? 和 setInterval() 所設置的 callback 函數。
  • pending callbacks: 這個 phase 執行一些與系統操作相關的 callback,比如建立 TCP 連接時收到的 ECONNREFUSED 相關的 callback 。
  • idle, prepare: 僅供Node.js內部使用。
  • poll: 從消息隊列里面獲取新的 I/O event,執行相應的 callback (不包括 setImmediate / close callback / 以及 timer 所設置的 callback)。
  • check: 執行通過 setImmediate()? 所設置的callback.
  • close callbacks: 執行一些 close callback ,比如通過這樣的代碼 socket.on('close', ...)? 所設置的 callback。

絕大部分情況下,這些 callback 是用 JS 寫的,Node 通過 Google V8 engine ,在主線程里面來執行這些 callback 。我們把上面的 6個 phase 和 tick 的關系放置到時間軸上,或許能更形象地說明主線程所做的工作。

圖片

圖 3:Node.js 主線程時序圖

(2)消息隊列

主線程不單單是在執行 JS code,也不僅僅只是在做 non-blocking I/O 操作。它在執行代碼的過程中,還會產生各種各樣的異步請求。直觀一點的如通過 setImmediate(callback[, ...args]) / fs.readFile(path[, options], callback) 產生,晦澀一點的如通過 Promise / async 產生。這些異步請求大部分情況下有一些共性:需要耗費一定的時間去處理。讓主線程放著其它事情不管,傻傻地干等這次操作的結果可不是聰明的做法。所以它們都會被封裝成 async Request,并被交給線程池去處理。還記得我們之前舉的餐館工作流程的例子嗎?燒菜是一個費時間的事情,如果小姐姐拿到我們的訂單,自己跑到后廚去燒菜會出現什么后果?等她把單子上的菜都燒好再去下一桌點菜的話,對客人而言就出現了一個 blocking I/O 操作:進餐館沒有人接待了。消息隊列就如同后廚那里的看板。小姐姐只負責往看板上添加新的訂單,而訂單的制作交由廚師團隊來完成。

(3)工作線程

工作線程來完成具體的 I/O 請求操作。通常這個過程藉由 OS 所提供的異步機制來完成。如 Windows 里面的 IO 完成端口(IOCP)、Linux 里面的異步 IO。如圖 2 所示,當工作線程完成了一個異步請求后,會把操作結果放置到一個消息隊列里面。從圖中可以看到,主線程運行所涉及到的每個 phase 都有各自專屬的消息隊列。消息隊列里面有了消息,意味著主線程又需要干活了,干活的過程中會繼續產生新的異步請求,工作線程繼續不知疲倦地搬磚。完美的閉環。有一種場景圖 2 并沒有畫出來,當 Node.js 收到來自系統外部的事件如網絡請求時,工作流程是什么樣子的?到目前為止我們談及的 event 都是由 JS code 主動觸發的,如果我們說這種 event 是由頂向下觸發的話,網絡請求這樣的 event 是由底向上觸發的。聰明的你一定可以在腦袋里大致畫出一條線出來:這條線的起點是位于內核的網卡驅動,終點是 Node.js 主線程,中間依次經過了內核協議棧,Node.js 的消息隊列。

3、小結

行文至此,可以看到 Node.js 是一個完完全全的消息驅動型模型。Node進程活著的最大意義是:有各種各樣的 event 以及綁定在 event 上面的 callback 和 data需要它(main thread 和 worker thread)處理。event 的 callback 中也可能會產生新的異步請求,進而產生新的 event 。正是這些源源不斷的 event 驅動著 Node 活下去。如果沒有event需要Node進程處理了,它也就沒有存在的必要了。Node.js 還是一個標準的單進行多線程模型。其中主線程用來執行我們所寫的 JS code ,而線程池里面的 worker thread 則用來執行各種耗時長的 I/O 操作。這些操作可能會導致 worker thread 被阻塞掉。worker thread 被阻塞沒有關系,但主線程被阻塞就不太美麗了。最后再強調一下:我們所寫的 JS code 是交由 V8 在單線程里面運行的,所以盡量不要在 JS code 里面執行耗時長的同步操作。

責任編輯:姜華 來源: 二哥聊云原生
相關推薦

2024-07-08 08:53:52

2014-03-07 13:43:32

Node.jsNode

2022-03-13 08:48:12

inspectorNode.js開發

2022-06-29 08:37:03

事件循環JS 語言

2015-03-10 10:59:18

Node.js開發指南基礎介紹

2013-11-01 09:34:56

Node.js技術

2023-04-28 15:20:37

JavaScript事件循環

2021-12-25 22:29:57

Node.js 微任務處理事件循環

2020-05-29 15:33:28

Node.js框架JavaScript

2012-02-03 09:25:39

Node.js

2017-10-09 18:54:20

前端Node.js貢獻代碼

2012-10-24 14:56:30

IBMdw

2011-11-10 08:55:00

Node.js

2011-09-08 13:46:14

node.js

2011-09-09 14:23:13

Node.js

2011-11-01 10:30:36

Node.js

2011-09-02 14:47:48

Node

2022-02-12 20:33:29

Node.jsStreamfetch API

2021-09-26 05:06:04

Node.js模塊機制

2021-11-06 18:40:27

js底層模塊
點贊
收藏

51CTO技術棧公眾號

国产精品白丝jk白祙喷水网站| 精品1区2区3区4区| 国产日韩v精品一区二区| 在线久久视频| 97在线精品| 性欧美长视频免费观看不卡| 九九热线视频只有这里最精品| 日韩一级电影| 99久久亚洲精品蜜臀| 97在线视频精品| 91se在线观看| 亚洲成人免费视| 欧美一区二区三区男人的天堂| 在线成人福利| 成人精品亚洲人成在线| 伊人av综合网| 触手亚洲一区二区三区| 在线播放视频一区| 久久久国产精品网站| 欧美黄色三级网站| 国产精品欧美日韩久久| 中文字幕日韩电影| 日韩理论片中文av| 成人免费在线观看网站| 午夜dj在线观看高清视频完整版| 99久久国产综合精品女不卡| 91精品国产91久久久久| 亚洲欧洲一级| 日韩精品一区二区三区中文不卡| 又黄又爽在线免费观看| 国产日韩欧美制服另类| 毛片在线导航| 亚洲视频在线免费看| 色a资源在线| 免费91麻豆精品国产自产在线观看| 日本一区二区综合亚洲| 手机在线一区二区三区| 日韩视频第一页| 久久99伊人| 午夜在线视频| 欧美变态tickling挠脚心| 先锋欧美三级| 国产经典av| 亚洲影视在线观看| 免费播放片a高清在线观看| 国产精品电影网| 国产精品美女久久久久久| 国产网站免费在线观看| 欧美影视资讯| 日本免费久久高清视频| 国产精品综合色区在线观看| 中文字幕国内自拍| 欧美日韩国产a| av在线日韩| 国产精品v欧美精品∨日韩| 亚洲三级小视频| 亚洲电影小说图| 欧美一级片一区| 日韩在线激情| 亚洲3p在线观看| 亚洲人成7777| 日韩欧美高清一区二区三区| 欧美日韩最好看的视频| 久久久精品天堂| 韩国成人动漫| 日本在线播放一区| 91久久一区二区| 一级毛片精品毛片| 18岁网站在线观看| 中文字幕精品国产| 国产一区二区精品在线观看| av在线天天| 国产成人综合网站| 蜜桃视频m3u8在线观看| 在线看日韩精品电影| 中文字幕伊人| 久久久久久久久久久人体 | 午夜av电影| 91久色国产| 亚洲va国产天堂va久久en| 国产剧情一区| av磁力番号网| 国模精品娜娜一二三区| 亚洲精华一区二区三区| 欧美日本在线视频| 亚洲黄色在线| 中日韩高清电影网| 黄色软件在线观看| 亚洲精品套图| 最新天堂资源在线| 粉嫩tv在线播放| 国产精品视频xxx| 国内精品一区二区三区四区| 国内精品美女在线观看| 波多野结衣的一区二区三区 | 91国产精品| 另类少妇人与禽zozz0性伦| 久久色在线视频| 欧美国内亚洲| 亚洲第一论坛sis| 天堂电影一区| 国产youjizz在线| 国产视频一区二区三区在线播放| 91精品国产综合久久久久久蜜臀| 91精品国产乱码久久久久久| 日产精品一线二线三线芒果| 精品久久久久久中文字幕| 精品无人区卡一卡二卡三乱码免费卡 | 日韩影院一区| 91精品国产色综合| 亚洲18色成人| 久久精品动漫| 国产日韩亚洲| 精品久久久久久久| 成人乱人伦精品视频在线观看| 六月婷婷一区| 青草国产精品| 亚洲色图图片| 在线观看av网| 91av入口| 中文字幕av不卡在线| 国产一区视频在线播放| 一区二区三区影院| 国产无人区一区二区三区| 亚洲欧美一区二区视频| 美女爽到高潮91| 深夜视频一区二区| 国产精品久av福利在线观看| 日韩理论在线| 97精品在线视频| 91久久精品日日躁夜夜躁国产| 日本精品一区| 国产伦精品一区二区三区精品视频| 秋霞久久久久久一区二区| 天天操,天天操| 国产精品网站在线播放| 精品99视频| 成人av免费观看| 日韩精品在线看片z| 91在线观看免费网站| 欧美在线观看www| 忘忧草在线影院两性视频| 中文.日本.精品| 国产探花一区在线观看| 国产一区二区亚洲| 激情亚洲小说| 成年人网站在线| 免费国产在线观看| 在线免费国产视频| 欧美激情黑人| 91超碰中文字幕久久精品| 91福利区一区二区三区| 欧美日韩亚洲综合在线 | 成人黄色在线看| 亚洲欧美另类在线| 久久久久九九视频| 一区二区三区产品免费精品久久75| 成人av免费在线播放| 国产精品久久久久天堂| 亚洲经典三级| 99在线精品免费视频九九视 | 亚洲an天堂an在线观看| 国产区二区三区| 婷婷综合影院| av男人的天堂在线观看| 久久99精品久久久野外观看| 99精品视频精品精品视频| 99久久影视| 日本vs亚洲vs韩国一区三区二区| 国产精品亚洲视频| 在线看日韩精品电影| 51午夜精品国产| 国产成人精品视频在线观看| a级黄色小视频| 国产免费网址| av中文在线资源库| 91久久中文| 在线91免费看| 久久综合网络一区二区| 欧美日韩视频在线一区二区 | 黄网免费入口| 精品国产亚洲日本| 亚洲精品不卡| 亚洲 日韩 国产第一区| 欧洲xxxxx| 精品免费一区二区| 日韩欧美国产系列| 在线人体午夜视频| 韩国毛片一区二区三区| 亚洲欧美一区二区精品久久久| 久久精品视频16| 欧美xxxxx视频| 亚洲视频一区二区免费在线观看| 久久精品视频导航| 国产精品麻豆免费版| 日本一极黄色片| 澳门成人av网| 精品国产第一福利网站| 黄色成人在线观看网站| 91精品国产自产拍在线观看蜜|