欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

分析node事件循環(huán)和消息隊(duì)列

 更新時(shí)間:2021年06月04日 14:26:08   作者:俗的太不一樣  
node的好處毋庸置疑,事件驅(qū)動(dòng),異步非阻塞I/O,以及處理高并發(fā)的能力深入人心,因此大家喜歡用node做一些小型后臺(tái)服務(wù)或者作為中間層和其他服務(wù)配合完成一些大型應(yīng)用場(chǎng)景。

什么是異步?

異步和同步應(yīng)該是經(jīng)常談的一個(gè)話題了。同步的概念很簡(jiǎn)單,自上而下依次執(zhí)行,必須等上邊執(zhí)行完下邊才會(huì)執(zhí)行。而異步可以先提交一個(gè)命令,中間可以去執(zhí)行別的事務(wù),而當(dāng)執(zhí)行完之后回過(guò)頭來(lái)返回之前的任務(wù)。

舉個(gè)例子:

你很幸運(yùn),找了一個(gè)漂亮的女朋友,有一天你的女朋友發(fā)短信問(wèn)你晚上看什么電影?但你并不知道看什么,馬上打開(kāi)電腦查了一下近期熱播的電影,這其中你女朋友一直在等你,這就是同步

而異步呢?還是你女朋友發(fā)短信問(wèn)你看什么電影,你跟她說(shuō): 你先等會(huì)吧吧,等我查一下,查好之后你回頭打電話告訴了她。這就是異步。

從而我們能看出同步和異步的一些特點(diǎn):

1.必須發(fā)生在兩個(gè)對(duì)象身上。(你和你女朋友)

2.必須發(fā)生一些事情。(看電影)

不同的就是:同步就是依次執(zhí)行,執(zhí)行完一個(gè)之后在執(zhí)行另一個(gè),直到執(zhí)行完成,而異步就是先執(zhí)行一個(gè),可能沒(méi)有執(zhí)行完成再去執(zhí)行另一個(gè),等第一個(gè)執(zhí)行完成后再返回結(jié)果

為什么需要異步呢?

答案很明顯,為了提高辦事的效率,CPU計(jì)算速度和磁盤(pán)的讀寫(xiě)速度差太遠(yuǎn)了,磁盤(pán)供不應(yīng)求,因此有了計(jì)算機(jī)的存儲(chǔ)系統(tǒng)的分層設(shè)計(jì),平衡了效率和成本??梢哉f(shuō)懶惰推動(dòng)人類的進(jìn)步,任何可以降低花費(fèi)時(shí)間而達(dá)到同等功效的方法肯定會(huì)被優(yōu)先采用。

發(fā)送短信時(shí)等待對(duì)方回復(fù)的時(shí)間純粹的浪費(fèi)掉了,CPU寫(xiě)入磁盤(pán)等待返回的結(jié)果的等待時(shí)間也被無(wú)情的消耗了,這是一個(gè)講究效率的時(shí)代完全不能忍受的,因此讓員工一直處于忙碌狀態(tài),最大限度的榨取員工價(jià)值是老板追求的,讓CPU和磁盤(pán)都不停的滿負(fù)荷處理事務(wù)也是效率需要的。因此,異步處理出現(xiàn)了。

什么是異步IO?

異步IO是指操作系統(tǒng)提供的IO(數(shù)據(jù)進(jìn)出)的能力,比如鍵盤(pán)輸入,對(duì)應(yīng)到顯示器上會(huì)有專門(mén)的數(shù)據(jù)輸出接口,這就是我們生活中可見(jiàn)的IO能力;這個(gè)接口在向下會(huì)進(jìn)入到操作系統(tǒng)這個(gè)層面,在操作系統(tǒng)中,會(huì)提供諸多的能力,比如:磁盤(pán)的讀寫(xiě),DNS的查詢,數(shù)據(jù)庫(kù)的連接啊,網(wǎng)絡(luò)請(qǐng)求的處理,等等;

在不同的操作系統(tǒng)層面,表現(xiàn)的不一致。有的是異步非阻塞的;有的是同步的阻塞的,無(wú)論如何,我們都可以看做是上層應(yīng)用于下層系統(tǒng)之間的數(shù)據(jù)交互;上層依賴于下層,但是反過(guò)來(lái),上層也可以對(duì)下層提供的這些能力進(jìn)行改造;如果這種操作是異步的,非阻塞的,那么這種就是異步非阻塞的異步IO模型;如果是同步的阻塞的,那么就是同步IO模型;

koa就是一個(gè)上層的web服務(wù)框架,全部由js實(shí)現(xiàn),他有操作系統(tǒng)之間的交互,全部通過(guò)nodejs來(lái)實(shí)現(xiàn);如nodejs的 readFile就是一個(gè)異步非阻塞的接口,readFileSync就是一個(gè)同步阻塞接口。

什么是事件循環(huán)?

事件循環(huán)是指Node.js執(zhí)行非阻塞I/O操作,盡管JavaScript是單線程的,但由于大多數(shù)內(nèi)核都是多線程的,node.js會(huì)盡可能將操作裝載到系統(tǒng)內(nèi)核。因此它們可以處理在后臺(tái)執(zhí)行的多個(gè)操作。當(dāng)其中一個(gè)操作完成時(shí),內(nèi)核會(huì)告訴Node.js,以便node.js可以將相應(yīng)的回調(diào)添加到輪詢隊(duì)列中以最終執(zhí)行。也就是說(shuō),js是單線程的,但是node運(yùn)行的時(shí)候其實(shí)是多線程的。(個(gè)人理解)而消息隊(duì)列是一個(gè)先進(jìn)先出的隊(duì)列,它里面存放著各種消息。

V8引擎

我們常說(shuō)的Chrome引擎和nodejs引擎就是V8引擎,他大致由以下組成:

這個(gè)引擎由內(nèi)存堆和調(diào)用棧組成,內(nèi)存堆就是負(fù)責(zé)進(jìn)行內(nèi)存分配,比如變量賦值,調(diào)用棧就是代碼執(zhí)行的地方。

調(diào)用棧中順序執(zhí)行主線程的代碼,當(dāng)調(diào)用棧中為空時(shí),js引擎會(huì)去消息隊(duì)列取消息。取到后就執(zhí)行。JavaScript是單線程的編程語(yǔ)言,意味著它有一個(gè)單一的調(diào)用棧。因此它只能在同一時(shí)間做一件事情。調(diào)用棧是一種數(shù)據(jù)結(jié)構(gòu),它基本上記錄了我們?cè)诔绦蛑械氖裁次恢?。如果我們步入一個(gè)函數(shù)中,我們會(huì)把這些數(shù)據(jù)放在堆棧的頂部。如果我們從一個(gè)函數(shù)中返回,這些數(shù)據(jù)將會(huì)從棧頂彈出。這就是堆棧的用途。調(diào)用棧中的每個(gè)條目叫做棧幀。堆和棧的區(qū)別就是先進(jìn)先出,一個(gè)先進(jìn)后出。

當(dāng)js運(yùn)行時(shí)

我們經(jīng)常使用的一些API并不是js引擎中提供的,例如定時(shí)器setTimeout。

它們其實(shí)是在瀏覽器中提供的,也就是運(yùn)行時(shí)提供的,因此,實(shí)際上除了JavaScript引擎以外,還有其他的組件。

其中有個(gè)組件就是由瀏覽器提供的,叫Web APIs,像DOM,AJAX,setTimeout等等。

然后還有就是非常受歡迎的事件循環(huán)和回調(diào)隊(duì)列。

運(yùn)行時(shí)負(fù)責(zé)給引擎線程發(fā)送消息,只負(fù)責(zé)生產(chǎn)消息,不負(fù)責(zé)取消息。

消息隊(duì)列

主線程在執(zhí)行過(guò)程中遇到了異步任務(wù),就發(fā)起函數(shù)或者稱為注冊(cè)函數(shù),通過(guò)event loop線程通知相應(yīng)的工作線程(如ajax,dom,setTimout等),同時(shí)主線程繼續(xù)向后執(zhí)行,不會(huì)等待。等到工作線程完成了任務(wù),eventloop線程會(huì)將消息添加到消息隊(duì)列中,如果此時(shí)主線程上調(diào)用棧為空就執(zhí)行消息隊(duì)列中排在最前面的消息,依次執(zhí)行。

新的消息進(jìn)入隊(duì)列的時(shí)候,會(huì)自動(dòng)排在隊(duì)列的尾端。

單線程意味著js任務(wù)需要排隊(duì),如果前一個(gè)任務(wù)出現(xiàn)大量的耗時(shí)操作,后面的任務(wù)得不到執(zhí)行,任務(wù)的積累會(huì)導(dǎo)致頁(yè)面的“假死”。這也是js編程一直在強(qiáng)調(diào)需要回避的“坑”。

主線程會(huì)循環(huán)上述步驟,事件循環(huán)就是主線程重復(fù)從消息隊(duì)列中取消息、執(zhí)行的過(guò)程。

需要注意的是 GUI渲染線程與JS引擎是互斥的,當(dāng)JS引擎執(zhí)行時(shí)GUI線程會(huì)被掛起,GUI更新會(huì)被保存在一個(gè)隊(duì)列中等到JS引擎空閑時(shí)立即被執(zhí)行。因此頁(yè)面渲染都是在js引擎主線程調(diào)用棧為空時(shí)進(jìn)行的。

其實(shí) 事件循環(huán) 機(jī)制和 消息隊(duì)列 的維護(hù)是由事件觸發(fā)線程控制的。

事件觸發(fā)線程 同樣是瀏覽器渲染引擎提供的,它會(huì)維護(hù)一個(gè) 消息隊(duì)列。

JS引擎線程遇到異步(DOM事件監(jiān)聽(tīng)、網(wǎng)絡(luò)請(qǐng)求、setTimeout計(jì)時(shí)器等...),會(huì)交給相應(yīng)的線程單獨(dú)去維護(hù)異步任務(wù),等待某個(gè)時(shí)機(jī)(計(jì)時(shí)器結(jié)束、網(wǎng)絡(luò)請(qǐng)求成功、用戶點(diǎn)擊DOM),然后由 事件觸發(fā)線程 將異步對(duì)應(yīng)的 回調(diào)函數(shù) 加入到消息隊(duì)列中,消息隊(duì)列中的回調(diào)函數(shù)等待被執(zhí)行。

同時(shí),JS引擎線程會(huì)維護(hù)一個(gè) 執(zhí)行棧,同步代碼會(huì)依次加入執(zhí)行棧然后執(zhí)行,結(jié)束會(huì)退出執(zhí)行棧。

如果執(zhí)行棧里的任務(wù)執(zhí)行完成,即執(zhí)行棧為空的時(shí)候(即JS引擎線程空閑),事件觸發(fā)線程才會(huì)從消息隊(duì)列取出一個(gè)任務(wù)(即異步的回調(diào)函數(shù))放入執(zhí)行棧中執(zhí)行。

以上就是分析node事件循環(huán)和消息隊(duì)列的詳細(xì)內(nèi)容,更多關(guān)于node事件循環(huán)和消息隊(duì)列的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • windows如何把已安裝的nodejs高版本降級(jí)為低版本(圖文教程)

    windows如何把已安裝的nodejs高版本降級(jí)為低版本(圖文教程)

    這篇文章主要介紹了windows如何把已安裝的nodejs高版本降級(jí)為低版本,本文分步驟通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • node.js 核心http模塊,起一個(gè)服務(wù)器,返回一個(gè)頁(yè)面的實(shí)例

    node.js 核心http模塊,起一個(gè)服務(wù)器,返回一個(gè)頁(yè)面的實(shí)例

    下面小編就為大家?guī)?lái)一篇node.js 核心http模塊,起一個(gè)服務(wù)器,返回一個(gè)頁(yè)面的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • Windows 系統(tǒng)下設(shè)置Nodejs NPM全局路徑

    Windows 系統(tǒng)下設(shè)置Nodejs NPM全局路徑

    這篇文章主要介紹了Windows 系統(tǒng)下設(shè)置Nodejs NPM全局路徑
    2016-04-04
  • Windows 系統(tǒng)下安裝和部署Egret的開(kāi)發(fā)環(huán)境

    Windows 系統(tǒng)下安裝和部署Egret的開(kāi)發(fā)環(huán)境

    Egret基于TypeScript開(kāi)發(fā)的,而TypeScript編譯工具tsc是基于Node.js 開(kāi)發(fā)的。所以在安裝過(guò)程中,我們先需要對(duì)于基礎(chǔ)支持工具進(jìn)行安裝。
    2014-07-07
  • 詳解node登錄接口之密碼錯(cuò)誤限制次數(shù)(含代碼)

    詳解node登錄接口之密碼錯(cuò)誤限制次數(shù)(含代碼)

    這篇文章主要介紹了nodejs登錄接口之密碼錯(cuò)誤限制次數(shù)(含代碼),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 如何刪除node_modules重新安裝的方法步驟

    如何刪除node_modules重新安裝的方法步驟

    我們?cè)陂_(kāi)發(fā)項(xiàng)目的時(shí)候,每次安裝的 node 包會(huì)出現(xiàn)版本和項(xiàng)目所需要的版本不一致的問(wèn)題,那么如何刪除node_modules重新安裝,本文就詳細(xì)的介紹一下
    2021-09-09
  • nodejs 的 session 簡(jiǎn)單使用

    nodejs 的 session 簡(jiǎn)單使用

    session 不用多介紹,使一個(gè)http可以對(duì)應(yīng)一個(gè)終端用戶,需要的朋友可以參考下。
    2016-06-06
  • Node.js常用工具之util模塊

    Node.js常用工具之util模塊

    util是一個(gè)Node.js核心模塊,提供常用函數(shù)的集合,用于彌補(bǔ)JavaScript的功能的不足,util模塊設(shè)計(jì)的主要目的是為了滿足Node內(nèi)部API的需求。下面這篇文章將詳細(xì)的介紹關(guān)于Node.js常用工具之util模塊的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-03-03
  • 帶你了解NodeJS事件循環(huán)

    帶你了解NodeJS事件循環(huán)

    這篇文章主要介紹NodeJS事件循環(huán),Node中代碼從上到下同步執(zhí)行,在執(zhí)行過(guò)程中會(huì)將不同的任務(wù)添加到相應(yīng)的隊(duì)列中,那具體有的循環(huán)又是怎么回事呢,限免現(xiàn)編就帶大家學(xué)習(xí)該詳細(xì)內(nèi)容,需要的朋友也可以參考一下
    2022-02-02
  • 關(guān)于Sequelize連接查詢時(shí)inlude中model和association的區(qū)別詳解

    關(guān)于Sequelize連接查詢時(shí)inlude中model和association的區(qū)別詳解

    這篇文章主要介紹了關(guān)于Sequelize連接查詢時(shí)inlude中model與association的區(qū)別,文中介紹的很詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-02-02

最新評(píng)論