摘要:實際上官方給出的單線程是具有誤導性的。如果開發者在回調函數中調用了阻塞方法比如上文中的函數,那么整個事件輪詢就會阻塞,事件隊列中的事件得不到及時處理。后記參考文章事件輪詢詳述
前言
總括 :
原文地址:理解Node.js的事件輪詢
Node小應用:Node-sample
智者閱讀群書,亦閱歷人生
正文 Node.js的兩個基本概念Node.js的第一個基本概念就是I/O操作開銷是巨大的:
所以,當前變成技術中最大的浪費來自于等待I/O操作的完成。有幾種方法可以解決性能的影響:
同步方式:按次序一個一個的處理請求。利:簡單;弊:任何一個請求都可以阻塞其他所有請求。
開啟新進程:每個請求都開啟一個新進程。利:簡單;弊:大量的鏈接意味著大量的進程。
開啟新線程:每個請求都開啟一個新線程。利:簡單,而且跟進程比,對系統內核更加友好,因為線程比進程輕的多;弊:不是所有的機器都支持線程,而且對于要處理共享資源的情況,多線程編程會很快變得太過于復雜。
第二個基本概念是每個連接都創建一個新線程是很消耗內存的(例如:你可以對比Nginx回想一下Apache內存耗盡的情景)。
Apache是多線程的:它為每個請求開啟一個新的線程(或者是進程,這取決于你的配置),當并發連接增多時,你可以看看它是怎么一點一點耗盡內存的。Nginx和Node.js不是多線程的,因為線程的消耗太“重”了。它們兩個是單線程、基于事件的,這就把處理眾多連接所產生的線程/進程消耗給消除了。
單線程確實只有一個線程:你不能并行執行任何代碼,比如:下面的“sleep”將會阻塞sever1秒鐘:
function sleep() { var now = new Data().getTime(); while (new Date().getTime() < now + 1000) { // do nothing } } sleep();
但就我目前學習階段而言,我覺得好多人對于所謂的node單線程是有誤解的。實際上官方給出的“單線程”是具有誤導性的。所謂的單線程是指你的代碼只運行在一個線程上(好多地方都叫它主線程,實際上Javascript的瀏覽器運行環境不也是這么處理我們寫的Javascript代碼的嘛),而諸多任務的并行處理,就需要多線程了,如下圖:
如上圖,Node.js中的單線程之說指的就是這個主線程,這個主線程有一個循環結構,保持著整個程序(你寫的代碼)的運轉。
事件輪詢其實上面我們所說的維持主線程運行的循環這部分就是"事件輪詢",它存在于主線程中,負責不停地調用開發者編寫的代碼。但對開發者是不可見的。so...開發者編寫的代碼是怎樣被調用的呢?看下圖:
如上圖,異步函數在執行結束后,會在事件隊列中添加一個事件(遵循先進先出原則),主線程中的代碼執行完畢后(即一次循環結束),下一次循環開始就在事件隊列中"讀取"事件,然后調用它所對應的回調函數(所以回調函數的執行順序是不一定的)。如果開發者在回調函數中調用了阻塞方法(比如上文中的sleep函數),那么整個事件輪詢就會阻塞,事件隊列中的事件得不到及時處理。正因為這樣,nodejs中的一些庫方法均是異步的,也提倡用戶調用異步方法。
var fs = require("fs"); fs.readFile("hello.txt", function (err, data) { //異步讀取文件 console.log("read file end"); }); while(1) { console.log("call readFile over"); }
如上代碼,我們雖然使用了異步方法readfile讀取文件,但read file end永遠不會輸出,因為代碼始終在while循環中,下一次事件輪詢始終沒法開始,也就沒法"讀取"事件隊列調用相應的回調函數了。
最后有一個Node-sample是博主平時積累的一些代碼,包含注釋,匯總成了一個小應用,還是可以看到學習的蛛絲馬跡的。感興趣的您可以看看。
后記參考文章:
Understanding the node.js event loop
nodejs事件輪詢詳述
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/86777.html
摘要:定時器階段這個是事件循環開始的階段,綁定到這個階段的隊列,保留著定時器的回調,盡管它并沒有將回調推入隊列中,但是以最小的堆來維持計時器并且在到達規定的事件后執行回調。 本文,將會詳細的講解 node.js 事件循環工作流程和生命周期 一些常見的誤解 在 js 引擎內部的事件循環 最常見的誤解之一,事件循環是 Javascript 引擎(V8,spiderMonkey等)的一部分。事實上...
摘要:檢索新的事件執行與相關的回調幾乎所有,除了由定時器調度的一些和將在適當的時候在這里阻塞。在事件循環的每次運行之間,檢查它是否在等待任何異步或定時器,如果沒有,則徹底關閉。 Node.js事件循環、定時器和process.nextTick() 什么是事件循環? 事件循環允許Node.js執行非阻塞I/O操作 — 盡管JavaScript是單線程的 — 通過盡可能將操作卸載到系統內核。 ...
摘要:回調函數執行幾乎所有的回調函數,除了關閉回調函數,定時器計劃的回調函數和。輪詢此階段有兩個主要的功能執行已過時的定時器腳本處理輪詢隊列中的事件。一旦輪詢隊列為空,事件循環將檢查已達到時間閾值的定時器。 什么是事件循環(Event Loop)? 事件環使得Node.js可以執行非阻塞I/O 操作,只要有可能就將操作卸載到系統內核,盡管JavaScript是單線程的。 由于大多數現代(終端...
摘要:的單線程,與它的用途有關。特點的顯著特點異步機制事件驅動。隊列的讀取輪詢線程,事件的消費者,的主角。它將不同的任務分配給不同的線程,形成一個事件循環,以異步的方式將任務的執行結果返回給引擎。 這兩天跟同事同事討論遇到的一個問題,js中的event loop,引出了chrome與node中運行具有setTimeout和Promise的程序時候執行結果不一樣的問題,從而引出了Nodejs的...
摘要:如果當前沒有事件也沒有定時器事件,則返回。相關資料關于的架構及設計思路的事件討論了使用線程池異步運行代碼。下一篇初窺事件機制的實現二中定時器的實現 在瀏覽器中,事件作為一個極為重要的機制,給予JavaScript響應用戶操作與DOM變化的能力;在Node.js中,事件驅動模型則是其高并發能力的基礎。 學習JavaScript也需要了解它的運行平臺,為了更好的理解JavaScript的事...
閱讀 2293·2021-11-15 11:37
閱讀 2962·2021-09-01 10:41
閱讀 797·2019-12-27 11:58
閱讀 753·2019-08-30 15:54
閱讀 719·2019-08-30 13:52
閱讀 2936·2019-08-29 12:22
閱讀 1080·2019-08-28 18:27
閱讀 1458·2019-08-26 18:42