node運(yùn)行原理 詳解nodejs異步I/O和事件循環(huán)?
詳解nodejs異步I/O和事件循環(huán)?Nodejs由單個(gè)線程運(yùn)行。它通過(guò)事件循環(huán)來(lái)獲取事件隊(duì)列中的消息以進(jìn)行處理。處理過(guò)程基本上是調(diào)用消息對(duì)應(yīng)的回調(diào)函數(shù)。消息隊(duì)列是在事件狀態(tài)發(fā)生變化時(shí)將消息按入隊(duì)列。
詳解nodejs異步I/O和事件循環(huán)?
Nodejs由單個(gè)線程運(yùn)行。它通過(guò)事件循環(huán)來(lái)獲取事件隊(duì)列中的消息以進(jìn)行處理。處理過(guò)程基本上是調(diào)用消息對(duì)應(yīng)的回調(diào)函數(shù)。消息隊(duì)列是在事件狀態(tài)發(fā)生變化時(shí)將消息按入隊(duì)列。因?yàn)樗菃尉€程的,所以當(dāng)JS文件中的代碼按順序執(zhí)行時(shí),事件循環(huán)被掛起。JS文件執(zhí)行后,事件循環(huán)開始運(yùn)行,從消息隊(duì)列中獲取消息,并開始執(zhí)行回調(diào)函數(shù)。因?yàn)榛卣{(diào)函數(shù)是單線程的,所以在執(zhí)行回調(diào)函數(shù)時(shí)事件循環(huán)被掛起。當(dāng)涉及到I/O操作時(shí),nodejs會(huì)打開一個(gè)獨(dú)立的線程進(jìn)行異步I/O操作,操作推送到消息隊(duì)列后,消息會(huì)被發(fā)送到服務(wù)器。
如何優(yōu)雅的處理Nodejs中的異步回調(diào)?
nodejs的亮點(diǎn)在于事件驅(qū)動(dòng)、無(wú)阻塞的I/O模型,這使得nodejs具有很強(qiáng)的并發(fā)處理能力,非常適合編寫網(wǎng)絡(luò)應(yīng)用程序。在nodejs中,大部分的I/O操作幾乎都是異步的,也就是說(shuō),我們需要在回調(diào)函數(shù)中處理I/O操作的結(jié)果,比如下面的函數(shù)來(lái)讀取文件的內(nèi)容:那么,如果我們讀取兩個(gè)文件并合并兩個(gè)文件的內(nèi)容,我們應(yīng)該怎么做呢?大多數(shù)沒(méi)有接觸過(guò)JS的人可能會(huì)這樣做:如果在許多類似的場(chǎng)景中,回調(diào)函數(shù)不是逐層嵌套的呢?這就是我們常說(shuō)的回調(diào)金字塔或回調(diào)地獄(http://callbackhell.com/)這也是小白最頭疼的問(wèn)題。這種層層嵌套的代碼給開發(fā)帶來(lái)了很多問(wèn)題,主要體現(xiàn)在以下幾個(gè)方面:~節(jié)點(diǎn).jsES6和ES7的無(wú)阻塞I/O模型非常優(yōu)秀,但它沒(méi)有匹配的描述語(yǔ)法。
畢竟,是JS問(wèn)題導(dǎo)致了節(jié)點(diǎn).js一種語(yǔ)言的異步性與其他語(yǔ)言的異步性有許多不同之處。
Nodejs中的異步到底是優(yōu)勢(shì)還是劣勢(shì)?
Nodejs在io處理上是異步的,這與JS引擎的原理是分不開的。如果所有耗時(shí)的操作都是同步的,那么當(dāng)前的JS主線程將被阻塞,從而導(dǎo)致并發(fā)請(qǐng)求的排隊(duì)阻塞。JS引擎只是將耗時(shí)的操作交給libuv的內(nèi)部線程池來(lái)處理,讓JS主線程等待接收l(shuí)ibuv的事件輪詢。