nodejs的機制是單線程,這個線程裏面,有一個事件循環機制,處理全部的請求。如圖所示。在事件處理過程當中,它會智能地將一些涉及到IO、網絡通訊等耗時比較長的操做,交由worker threads去執行,執行完了再回調,這就是所謂的異步IO非阻塞吧。可是,那些非IO操做,只用CPU計算的操做,它就本身扛了,好比算什麼斐波那契數列之類。它是單線程,這些本身扛的任務要一個接着一個地完成,前面那個沒完成,後面的只能乾等。所以,對CPU要求比較高的CPU密集型任務多的話,就有可能會形成號稱高性能,適合高併發的node.js服務器反應緩慢。javascript
輪詢技術的缺點在於應用程序要主動調用,會形成佔用較多CPU時間片,性能較爲低下。html
理想的異步I/O應該是應用程序發起異步調用,而不須要進行輪詢,進而處理下一個任務,只需在I/O完成後經過信號或是回調將數據傳遞給應用程序便可。java
Node只是表面暴露給用戶的javascript代碼是單線程的,底層仍是多線程的。
Node.js選擇的異步I/O方案:因爲Windows平臺和*nix平臺的差別,Node.js提供了libuv來做爲抽象封裝層,使得全部平臺兼容性的判斷都由這一層次來完成,保證上層的Node.js與下層的libeio/libev及IOCP之間各自獨立。Node.js在編譯期間會判斷平臺條件,選擇性編譯unix目錄或是win目錄下的源文件到目標程序中。node
每次循環中,它會調用IOCP相關的GetQueuedCompletionStatus方法檢查是否線程池中有執行完的請求,若是存在,poll操做會將請求對象加入到loop的pending_reqs_tail屬性上。 另外一邊這個循環也會不斷檢查loop對象上的pending_reqs_tail引用,若是有可用的請求對象,就取出請求對象的result屬性做爲結果傳遞給oncomplete_sym執行,以此達到調用JavaScript中傳入的回調函數的目的。 至此,整個異步I/O的流程完成結束。其流程以下:git
使用Node的時候,會在javascript觸發一些命令調用方法,這些方法會被包裝成一個對象,放入線程池,而後前面的方法就返回了,繼續執行下面的JS代碼。
線程池中採用多線程的方式執行,執行完的對象放入事件循環隊列。
事件循環隊列採用相似while(true)這種循環的方式,不斷的查看是否有事件,而且讀取是否包含回調,因爲前面回調函數被包裝到對象中,這裏直接調用執行就能夠了。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------github
- npm:NodeJs包管理器
- express:服務器端比較流行的MVC框架,處理服務請求,路由轉發,邏輯處理
- mongoose:mongodb包裝,更方便使用數據庫
- http://socket.io:實現服務端和客戶端socket通訊解決方案
- backbone:客戶端MVC框架,編寫客戶端應用(豆瓣說)
- coffeescript:提升JavaScript的可讀性,健壯性
- zombie:瀏覽器子集,編寫html解析器,輕形javascript客戶端測試
------------------------------------------------------------------------------------------------------------------------------------------------------------------------mongodb
一、進入 http://nodejs.org 下載開發環境chrome
http://Expressjs.com 下載安裝Express npm install -g express數據庫
繼續安裝ejs:npm install ejsexpress
若是要想運行Node.js程序,則如今只可以使用「node app.js」,而這樣的運行方式,若是在app.js文件修改以後每每須要從新啓動才能夠加載新的內容,這對於開發是很是不方便的, 爲此,可使用一個supervisor組件包,它能夠動態的加載修改以後的開發程序。
下載安裝supervisor
npm install -g supervisor
利用supervisor方式運行程序
supervisor app.js
二、
調試代碼:進入npm目錄安裝supervisor。 -g 表示全局模式
npm install -supervisor -g
安裝supervisor 來控制調試代碼。 不須要每次中止重啓node.js的服務
使用supervisor app.js啓動
四、回調函數:調用時所作的工做知識將異步式IO請求發送給了操做系統,而後當即返回並執行後面的語句,執行完之後進入事件循環監聽事件,當fs接受到IO請求完成的事件時。事件循環會主動調用回調函數完成後續工做。同步則是阻塞等待完成後,繼續執行。
五、事件
a.普通事件的使用
//聲明事件對象`
var EventEmitter=require('events').EventEmitter;
var event=new EventEmitter();
//註冊事件
event.on('some_event',function(){
console.log('這是一個自定義的事件');
});
//觸發事件
setTimeout(function(){
event.emit('some_event');
},1000);
b.Node.js的事件循環機制
(1)Node.js在何時進入事件循環呢?
Node.js程序是由事件循環開始,到事件循環結束,全部的邏輯都是事件的回調函數。
(2)如何使用自定義事件呢?
事件的回調函數在執行的過程當中,可能會發出IO請求或直接發射(emit)事件,執行完畢後再返回事件循環。
六、模塊:Node.js提供了exports和require兩個對象,其中exports是模塊公開的接口,require用於從外部獲取一個模塊的接口,即獲取模塊的exports對象。exports自己僅僅是一個普通的空對象,即{},它是專門用來聲明接口
七、包是在模塊基礎上更深一步的抽象,Node.js的包相似於C/C++的函數庫或者java的類庫,它講某個獨立的功能封裝起來,用於發佈、更新、依賴管理的版本控制。npm解決包的發佈和獲取需求。
Node.js包管理器,即npm是Node.js官方提供的包管理工具,它已經成了Node.js包的標準發佈平臺,用於Node.js包的發佈、傳播、依賴控制。
(1)獲取一個包
npm [install/i] [package_name]
例如安裝express包:
npm i express
卸載包:
npm uninstall 包名 [-g]
查看當前全部包:
npm list
....
(2)本地模式和全局模式
a.默認是npm install 包名 做爲本地模式
b.全局模式
npm install -g 包名
c.區別和用法
由於本地模式不會註冊PATH環境變量,舉例,咱們安裝supervisor是爲了在命令行中運行它,譬如直接運行supervisor scirpt.js。
npm本地模式僅僅把包安裝到了node_modules子目錄下,其中的bin目錄沒有包含在PATH環境變量中,調用。不能直接在命令行中
使用全局模式安裝的包並不能直接在javascript文件中require得到,由於require不會搜索/usr/local/lib/node_modules。
通俗講:
當咱們要把某個包做爲工程運行時的一部分時,經過本地模式獲取,若是在命令行下使用,則使用全局模式。
d.包的發佈
首選確保具有CommonJS爲基礎包的規範,但與CommJS並不徹底一致,其主要差異在於必填字段的不一樣,經過使用npm init能夠根據交互式問答產生一個符合標準的package.json
dos進入這個目錄運行 npm init獲得package.json的文件,改爲本身的文件等信息
而後進入package.json所在目錄運行 npm publish 就完成了發佈
如何更新包?
若是你的包內容有改動,則在版本上做改動,運行npm publish
npm unpublish
八、調試代碼
在eclipse裝插件
在debug中配置 端口爲5858
在命令行運行js文件的時候
node --debug-brk=5858 文件名.js
如今就在ecplise中啓動debug就能夠跟斷點了
Google Dart
九、全局對象與全局變量:全部屬性均可以在程序的任何地方訪問,即全局變量。在JavaScript中,一般window是全局對象,而Node.js的全局對象是global,全部全局變量都是global對象的屬性,如:console、process等。
十、