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