NodeJS 學習筆記1

首先,創建個hello.js的文件,在文件中copy如下代碼:

複製代碼
  var http = require('http');
  http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
  }).listen(1337, "127.0.0.1");
  console.log('Server running at http://127.0.0.1:1337/');
複製代碼

  代碼邏輯:

   a. 全局方法require()是用來導入模塊的,一般直接把 require() 方法的返回值賦值給一個變量,在 JavaScript 代碼中直接使用此變量即可 。require("http") 就是加載系統預置的 http 模塊

   b. http.createServer 是模塊的方法,目的就是創建並返回一個新的web server對象,並且給服務綁定一個回調,用以處理請求。

   c. 通過 http.listen() 方法就可以讓該 HTTP 服務器在特定端口監聽。

   d. console.log就不用多說了,瞭解firebug的都應該知道,Node實現了這個方法。

    注: 想了解具體細節請查看文檔 cnodejs.org/cman/all.html#http.createServer

  接着運行Node服務器,執行hello.js代碼,成功啓動會看見console.log()中的文本。有圖有真相:

  

  

 

npm的下載和使用

  除Node本身提供的API外,現在有不少第三方模塊可極大的提高開發效率,npm就是Node的軟件包管理器,可以用它安裝所需軟件包併發布自己爲nodejs寫的軟件包。官網地址:npmjs.org

  安裝只需要在終端寫入一行代碼:    

  curl http://npmjs.org/install.sh | sh

  npm安裝node擴展包同樣是一行代碼:  

  npm install <包名>    //例:npm install express

  注:如果安裝模塊的過程中報域名錯誤的話,請清空緩存 >npm cache clean 或重啓計算機即可。

  

理解Node的模塊概念

  在Node中,不同的功能組件被劃分成不同的模塊。應用可以根據自己的需要來選擇使用合適的模塊。每個模塊都會暴露一些公共的方法或屬性。模塊的使用者直接使用這些方法或屬性即可,對於內部的實現細節就可以不用瞭解。除了Node本身提供的API外,開發人員也可以利用這個機制來將應用拆分成多個模塊,以提高代碼的可複用性。

  1.如何使用模塊?

  在Node中使用模塊是非常方便的,在 JavaScript 代碼中可以直接使用全局函數 require() 來加載一個模塊。

  在剛剛”Hello World"的例子中,require("http") 可以加載系統預置的 http 模塊;模塊名稱以 "./" 開始的,如 require("./myModule.js") 用來加載與當前 JavaScript 文件同一目錄下的 myModule.js 模塊。

  2.自己如何開發模塊?

  剛剛介紹使用require()導入模塊的時候,模塊名稱以 "./" 開始的這種,就是自己開發的模塊文件。需要注意的就是JS文件的系統路徑。

  代碼中封裝了模塊的內部處理邏輯,一個模塊一般都會暴露一些公開的方法或屬性給其他的人使用。模塊的內部代碼需要把這些方法或屬性給暴露出來。

  3.來一套簡單的例子。先創建一個模塊文件如myModule.js,就一行代碼

  console.log('Hi Darren.')

  然後創建一個test.js文件,導入這個JS文件,執行node看到結果

  現在Node社區中已有不少第三方的模塊,希望能有更多人通過學習Node,加入到這個大家庭中,爲Node社區來添磚加瓦。先謝謝之,咱們繼續。  

  4.來一個深點的例子。這個例子中將會針對 私有和共有 進行介紹。先創建一個myModule.js,代碼如下:

  var name = "Darren";
  this.location = "Beijing";
  this.showLog = function(){
      console.log('Hi Darren.')
  };

  代碼中出現了三種類型,分別是: 私用屬性,共有屬性和共有方法,再創建一個test.js,執行Node

  結果高亮的地方很清楚的告訴我們,私有方法我們在模塊以外是取不到的,所以是undefined。共有屬性和共有方法的聲明需要在前面加上 this 關鍵字。

 

Node能做什麼和它的優勢

  Node核心思想:  1.非阻塞;  2.單線程;  3.事件驅動

  在目前的web應用中,客戶端和服務器端之間有些交互可以認爲是基於事件的,那麼AJAX就是頁面及時響應的關鍵。每次發送一個請求時(不管請求的數據多麼小),都會在網絡裏走一個來回。服務器必須針對這個請求作出響應,通常是開闢一個新的進程。那麼越多用戶訪問這個頁面,所發起的請求個數就會越來越多,就會出現內存溢出、邏輯交錯帶來的衝突、網絡癱瘓、系統崩潰這些問題。

  Node的目標是提供一種構建可伸縮的網絡應用的方案,在hello world例子中,服務器可以同時處理很多客戶端連接。

  Node和操作系統有一種約定,如果創建了新的鏈接,操作系統就將通知Node,然後進入休眠。如果有人創建了新的鏈接,那麼它(Node)執行一個回調,每一個鏈接只佔用了非常小的(內存)堆棧開銷。    

  舉一個簡單的異步調用的例子,把test.js和myMydule.js準備好了,^_^。把以下代碼拷貝到test.js中並執行:

複製代碼
  var fs = require('fs');
  fs.readFile('./myModule.js', function (err, data) {
    if (err) throw err;
    console.log('successfully');
  });
  console.log('async');
複製代碼

  所謂的異步,大家應該都能想得到運行時會先打先顯示"async",再顯示"successfully"。

  Node是無阻塞的,新請求到達服務器時,不需要爲這個請求單獨作什麼事情。Node僅僅是在那裏等待請求的發生,有請求就處理請求。

  Node更擅長處理體積小的請求以及基於事件的I/O。

  Node不僅僅是做一個Web服務的框架,它可以做更多,比如它可以做Socket服務,可以做比方說基於文件的,然後基於像一些比方說可以有子進程,然後內部的,它是一個很完整的事件機制,包括一些異步非注射的解決方案,而不僅僅侷限在網絡一層。同時它可能,即使作爲一個Web服務來說,它也提供了更多可以深入這個服務內核、核心的一些功能,比方說Node使用的Http Agent,這塊就是它可以更深入這個服務內核來去做一些功能。

 

Node事件流概念

  因爲Node 採用的是事件驅動的模式,其中的很多模塊都會產生各種不同的事件,可由模塊來添加事件處理方法,所有能夠產生事件的對象都是事件模塊中的 EventEmitter 類的實例。代碼是全世界通用的語言,所以我們還是用代碼說話:

複製代碼
  var events = require("events"); 
  var emitter = new events.EventEmitter(); 
  emitter.on("myEvent", function(msg) { 
    console.log(msg); 
  }); 
  emitter.emit("myEvent", "Hello World.");
複製代碼

  簡單的分析這段:

   1. 使用require()方法添加了events模塊並把返回值賦給了一個變量

   2. new events.EventEmitter()這句創建了一個事件觸發器,也就是所謂的事件模塊中的 EventEmitter 類的實例

   3. on(event, listener)用來爲某個事件 event 添加事件處理方法監聽器

   4. emit(event, [arg1], [arg2], [...]) 方法用來產生事件。以提供的參數作爲監聽器函數的參數,順序執行監聽器列表中的每個監聽器函數。

 

  EventEmitter 類中的方法都與事件的產生和處理相關:

   1. addListener(event, listener) 和 on(event, listener) 這兩個方法都是將一個監聽器添加到指定事件的監聽器數組的末尾

   2. once(event, listener) 這個方法爲事件爲添加一次性的監聽器。該監聽器在事件第一次觸發時執行,過後將被移除

   3. removeListener(event, listener) 該方法用來將監聽器從指定事件的監聽器數組中移除出去

   4. emit(event, [arg1], [arg2], [...]) 剛剛提到過了。

  在Node中,存在各式各樣不同的數據流,Stream(流)是一個由不同對象實現的抽象接口。例如請求HTTP服務器的request是一個流,類似於stdout(標準輸出);包括文件系統、HTTP 請求和響應、以及 TCP/UDP 連接等。流可以是可讀的,可寫的,或者既可讀又可寫。所有流都是EventEmitter的實例,因此可以產生各種不同的事件。

  可讀流主要會產生以下事件:

  • data   當讀取到流中的數據時,此事件被觸發
  • end   當流中沒有數據可讀時,此事件被觸發
  • error   當讀取數據出現錯誤時,此事件被觸發
  • close   當流被關閉時,,此事件被觸發,可是並不是所有流都會觸發這個事件。(例如,一個連接進入的HTTP request流就不會觸發'close'事件。)

  還有一種比較特殊的 fd 事件,當在流中接收到一個文件描述符時觸發此事件。只有UNIX流支持這個功能,其他類型的流均不會觸發此事件。

  相關詳細文檔:http://cnodejs.org/cman/all.html#events_

 

強大的File System 文件系統模塊

  Node 中的 fs 模塊用來對本地文件系統進行操作。文件的I/O是由標準POSIX函數封裝而成。需要使用require('fs')訪問這個模塊。所有的方法都提供了異步和同步兩種方式。

  fs 模塊中提供的方法可以用來執行基本的文件操作,包括讀、寫、重命名、創建和刪除目錄以及獲取文件元數據等。每個操作文件的方法都有同步和異步兩個版本。

  異步操作的版本都會使用一個回調方法作爲最後一個參數。當操作完成的時候,該回調方法會被調用。而回調方法的第一個參數總是保留爲操作時可能出現的異常。如果操作正確成功,則第一個參數的值是 null 或 undefined 。

  同步操作的版本的方法名稱則是在對應的異步方法之後加上一個 Sync 作爲後綴。比如異步的 rename() 方法的同步版本是 renameSync() 。下面列出來了 fs 模塊中的一些常用方法,都只介紹異步操作的版本。

  test.js和myModule.js文件準備好了木?把下面這段代碼copy到test.js中執行一次

  var fs = require('fs');
  fs.unlink('./myModule.js', function (err) {
    if (err) throw err;
    console.log('successfully deleted myModule.js');
  });

  如果沒有報error,那麼myModule.js就被刪除了,就是這麼簡單

  

  這只是一個簡單的例子,感興趣的話自己去多多嘗試,實踐出真理。由於篇幅原因就不多舉例了。^_^

   推薦學習網站:https://cnodejs.org/getstart

        http://nqdeng.github.io/7-days-nodejs/#1.1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章