Nodejs開發指南-快速入門

3.1Nodejs編程
3.1.1 Hello world
打開記事本

console.log('Hello world!');

3.1.2 node.js命令行工具
3.1.3 建立http服務器

Paste_Image.png
Paste_Image.png

node.js最簡單的http服務器就這樣誕生了,這個程序調用了nodejs提供的http模塊,對所用HTTP請求答復同樣的內容并監聽3000端口。

小技巧--使用supervisor
改動nodejs代碼自動重啟服務器。
npm install -g supervisor

3.2 異步式I/O和事件式編程
nodejs最大的特點就是異步式I/O(或者非阻塞I/O)與事件緊密結合的編程模式,這種編程模式與傳統的同步式I/O線性編程思路有很大的不同,因為控制流很大程度上要靠事件和回調函數來組織,一個邏輯要拆分為若干個單元。
3.2.1 阻塞與線程
什么是阻塞(block)呢?線程在執行中如果遇到磁盤讀寫或網絡通信(統稱I/O操作),通常要耗費較長的時間,這時操作系統會剝奪這個線程的CPU控制權,使其暫停執行,同時將資源讓給其他的工作線程,這種線程調度方式稱為阻塞。當I/O操作完畢時。操作系統將這個線程的阻塞狀態刪除,恢復其對CPU的控制權。令其繼續執行。這種I/O模式就是通常的同步式I/O(Synchronous I/O)或阻塞式I/O(Blocking I/O)。
異步式I/O(Asynchronous I/O)或非阻塞式I/O(Non-blocking I/O)則針對所有的I/O操作不采用阻塞的策略。當線程遇到I/O操作時,不會以阻塞的方式等待I/O操作的完成或數據的返回,而只是將I/O請求發送給操作系統,繼續執行下一條語句。當操作系統完成I/O操作時,以事件的形式通知執行I/O操作的線程,線程會在特定時間處理這個事件,為了處理異步I/O,線程必須有事件循環,不斷地檢查有沒有處理的事件,依次予以處理。
阻塞模式下,一個線程處理一項任務,多線程提高系統吞吐量。
非阻塞模式下,一個線程永遠在執行計算操作,CPU利用率100%,I/O以事件方式通知。線程不會被I/O阻塞,永遠在利用CPU。

多線程同步式I/O
單線程異步式I/O

優點:單線程事件驅動的異步式I/O比傳統的多線程阻塞式I/O好在哪里?
異步式I/O少了多線程的開銷,對操作系統來說,創建一個線程的代繳是十分昂貴的,需要給他分配內存,列入調度,同時在線程切換的時候執行內存換頁,CPU的緩存被清空,切換回來的時候還要重新從內存中讀取信息,破壞了數據的局部性。
缺點:不符合人們一般的程序設計思維,容易讓控制流變得晦澀難懂,給編碼和調試帶來不小的困難。習慣傳統編程模式的開發者在剛剛接觸到大規模的異步應用時往往會無所適從,有不少解決異步式編程問題的庫。

Paste_Image.png

3.2.2 回調函數
nodejs中如何用異步的方式讀取一個文件
代碼如下:


讀取文件代碼

結果如下:


Paste_Image.png

同步式讀取文件
代碼如下:


Paste_Image.png

結果如下:


Paste_Image.png

同步式讀取文件的方式比較好理解。
異步式讀取文件:異步式I/O請求發送給了操作系統,然后立即返回并執行后面的語句,執行完以后進入事件循環監聽事件,當fs接收到I/O請求完成的事件時,事件循環會主動調用回調函數以完成后續工作。

3.2.3 事件


事件循環

3.3 模塊和包
一個node.js文件就是一個模塊(這個文件可能是javascript代碼、json或者編譯過的c/c++擴展)
3.3.2
1、創建模塊
module.js

//module.js
var name;
exports.setName = function(thyName){
  name = thyName;
};
exports.sayHello = function(){
  console.log('hello'+ name);
};

在同一目錄下創建getmodule.js

//getmodule.js
var myModule = require('./module');
myModule.setName('BYVoid');

module.js通過exports對象把setName和sayHello作為模塊的訪問接口,在getmodule.js中通過require('./module')加載這個模塊,然后就可以直接訪問module.js中exports對象的成員函數了。
2.單次加載

無論調用多少次require。獲得的模塊都是同一個

  1. 覆蓋exports
    3.3.3創建包
    node.js的包是個目錄。
    CommonJS規范的包應該具備以下特征:
package.json 必須在包的頂層目錄下
二進制文件應該在bin目錄下
javascript代碼必須在lib目錄下
文檔應該在doc目錄下
單元測試應該在test目錄下

1 作為文件i一個叫做somepackage的文件夾,在其中創建index.js

//somepackage/index.js
exports.hello = function(){
  console.log('hello.');
};
然后在somepackage之外建立getpackage.js
//getpackage.js
var somePackage = require('./somepackage');
somePackage.hello();

運行 node getpackage.js 控制臺將輸出結果hello .
我們把文件夾封裝成模塊,即所謂的包,包通常是一些模塊的集合,在模塊的基礎上提供了更高的抽象,相當于提供了一些固定接口的函數庫,通過定制package.json,我們可以創建更復雜、更完善、更符合規范的包用于發布。
2 package.json
在somepackage中創建package.json

{
  'main':'./lib/interface.js'
}

然后將index.js重命名為interface.js并放入lib子文件下。以同樣的方式再次調用這個包,依然可以正常使用。
node.js在調用某個包時,會首先檢查包中package.json文件的main字段,將其作為包的接口模塊,如果package.json或main字段不存在,會嘗試尋找index.js或index.node作為包的接口。

package.json 是CommonJS規定的用來描述包的文件,完全符合規范的package.json文件應該含有以下字段
name:包的名稱,必須唯一,由小寫英文字母、數字和下劃線組成,不能包含空格
description:包的簡要說明
version:符合語義化版本識別規范的版本字符串
keywords:關鍵詞數組,通常用于搜索
maintainers:維護者數組,每個元素要包含name、email(可選)、web(可選)字段
contributors:貢獻者數組,格式與maintainers相同,包的作者應該是貢獻者數組的第一個元素
bugs:提交bug的地址,可以是網址或者電子郵件地址
licenses:許可證數組,每個元素要包含type(許可證的名稱)和Url(鏈接到許可證文本的地址)字段
repositories:倉庫托管地址數組,每個元素要包含type(倉庫的類型,如git)、url(倉庫地址)和path(相對于倉庫的路徑,可選)字段
dependencies:包的依賴,一個關聯數組,由包名稱和版本號組成

{
  "name": "mypackage",
  "description": "Sample package for CommonJS. This package demonstrates the requiredelements of a CommonJS package.",
  "version": "0.7.0",
  "keywords": ["package","example"],
  "maintainers": [{"name": "Bill Smith","email": "bills@example.com",}],
  "contributors": [{"name": "BYVoid","web": "http://www.byvoid.com/"}],
  "bugs": {"mail": "dev@example.com","web": "http://www.example.com/bugs"},
  "licenses": [{"type": "GPLv2","url": "http://www.example.org/licenses/gpl.html"}],
  "repositories": [{"type": "git","url": "http://github.com/BYVoid/mypackage.git"}],
  "dependencies": {"webkit": "1.2","ssl": {"gnutls": ["1.0", "2.0"],"openssl": "0.9.8"}}
}

3.3.4 Nodejs包管理
1獲取一個包

npm [install/i] [package_name]
例如你要安裝express
npm install express

2npm全局模式
npm install -g supervisor:同時在PATH環境變量中注冊supervisor

在mac/Linux 全局模式安裝需要root權限

Paste_Image.png

3創建全局連接
全局模式安裝的包不能通過require使用,但是通過npm link 可以打破這一局限(不支持windows)

npm link express 
./node_modules/express > /usr/local/bin/node_modules/express

除了將全局的包連接到本地以外,npm link還可以將本地的包連接到全局,使用方法(在package.json所在目錄)中運行npm link,如果我們要開發一個包,利用這種方法可以非常方便地在不同的工程間進行測試。

4包的發布
npm 可以非常方便地發布一個包,比 pip、 gem、 pear 要簡單得多。在發布之前,首先需要讓我們的包符合 npm 的規范, npm 有一套以 CommonJS 為基礎包規范,但與 CommonJS并不完全一致,其主要差別在于必填字段的不同。通過使用 npm init 可以根據交互式問答產生一個符合標準的 package.json,例如創建一個名為 byvoidmodule 的目錄,然后在這個目錄中運行npm init:

$ npm init
Package name: (byvoidmodule) byvoidmodule
Description: A module for learning perpose.Package 
version: (0.0.0) 0.0.1
Project homepage: (none) http://www.byvoid.com/
Project git repository: (none)
Author name: BYVoidAuthor 
email: (none) byvoid.kcp@gmail.com
Author url: (none) http://www.byvoid.com/
Main module/entry point: (none)Test command: (none)
What versions of node does it run on? (~0.6.10)
About to write to/home/byvoid/byvoidmodule/package.json
{
  "author": "BYVoid <byvoid.kcp@gmail.com>(http://www.byvoid.com/)",
  "name": "byvoidmodule",
  "description": "A module for learning perpose.",
  "version": "0.0.1",
  "homepage": "http://www.byvoid.com/",
  "repository": {
     "url": ""
   },
   "engines":{
      "node": "~0.6.12"
    },
   "dependencies": {},
   " devDependencies": {}
}

Is this ok? (yes) yes

這樣就在 byvoidmodule 目錄中生成一個符合 npm 規范的 package.json 文件。創建一個index.js 作為包的接口,一個簡單的包就制作完成了。在發布前,我們還需要獲得一個賬號用于今后維護自己的包,使用 npm adduser 根據提示輸入用戶名、密碼、郵箱,等待賬號創建完成。完成后可以使用 npm whoami 測驗是否已經取得了賬號。接下來,在 package.json 所在目錄下運行 npm publish,稍等片刻就可以完成發布了。打開瀏覽器,訪問 http://search.npmjs.org/ 就可以找到自己剛剛發布的包了。現在我們可以在世界的任意一臺計算機上使用 npm install byvoidmodule 命令來安裝它。圖3-6 是npmjs.org上包的描述頁面。
如果你的包將來有更新,只需要在 package.json 文件中修改 version 字段,然后重新使用 npm publish 命令就行了。如果你對已發布的包不滿意(比如我們發布的這個毫無意義的包),可以使用 npm unpublish 命令來取消發布。
3.4 調試
寫一個簡單的代碼

Paste_Image.png

在命令行下執行 node debug debug.js,將會啟動調試工具:

Paste_Image.png
Paste_Image.png

Paste_Image.png

3.4.2 遠程調試
3.4.4 使用node-inspector調試nodejs
大部分基于 Node.js 的應用都是運行在瀏覽器中的,例如強大的調試工具 node-inspector。node-inspector 是一個完全基于 Node.js 的開源在線調試工具,提供了強大的調試功能和友好的用戶界面,它的使用方法十分簡便。首先,使用 npm install -g node-inspector 命令安裝 node-inspector,然后在終端中通過 node --debug-brk=5858 debug.js 命令連接你要除錯的腳本的調試服務器,啟動 node-inspector:$ node-inspector在瀏覽器中打開 http://127.0.0.1:8080/debug?port=5858, 即可顯示出優雅的 Web 調試工具

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,681評論 25 708
  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,107評論 0 1
  • 今天父母回老家去了,他們是帶著牽掛,帶著傷心走的。我也很難過,他們一大把年紀,千里路上奔波,卻因為弟弟的不懂事,難...
    劉小英anny閱讀 250評論 3 8
  • 2015.7.17 晴 藍再度因想情節過頭,晚睡了,反復而又模糊的夢境像一只犯了神經病的貓,它扯著黑色的毛線球在她...
    c9fcba0c9e58閱讀 485評論 0 1
  • 關注互聯網,關注硅谷堂。想獲取大量運營電子書籍,關注硅谷堂(ID:guigutang)公眾號,回復“書單”,即可獲...
    硅谷堂閱讀 265評論 0 0