Nodejs --我本身的學習筆記

 

     對於Nodejs,相信客官並不陌生,網上卻已衆說紛紜,有人說是一個平臺,有人說是服務器JavaScript,有人說一個框架…html

   以前亦有過研究,多懷可遠觀而不可褻玩也。高效率,I/O操做,異步編程,以及高併發處理!!java

   因而乎,懷着這份忐忑與景仰yu好奇,以前有自學過一段時間,這些日子公司項目完測,遂整理了一些Nodejs學習筆記,這裏純屬分享下本身的筆記(說不定之後還能奉承寶典咧,想一想都有點雞凍)也有從別處借鑑過來的知識,如有雷同,不勝榮幸,供客官參考,若有不足多多指教node

 

推薦讀書 樸靈《深刻淺出nodeJsweb

推薦文章Darren_聶微東《node.js 初體驗》

 

 ok,不廢話,手記攤開npm

 

旨在提供一種簡單的構建可伸縮網絡程序的方法編程

 這是Nodejs官方的宣言json

 哈哈哈,這逼裝的我要給103分,不解釋windows

 

Node.js是啥?數組

  Nodejs 不是一種獨立的語言瀏覽器

  Nodejs 是一個讓JavaScript運行在服務端的開發的平臺

  服務器端的JavaScript
  容許開發人員使用JavaScript語言寫服務器端代碼的框架(其實Nodejs是對Commonjs規範的一種很好的實現)

  其自己利用Google V8 JavaScript引擎,因此速度和性能很是好,並且Nodejs又對其進行了封裝,同時還改進了其處理二進制數據的能力(Nodejs對引入過的模塊都會進行緩存,且核心模塊的緩存檢查先於文件模塊的緩存檢查)
  Nodejs不是一個web服務器,只是計算機上執行代碼的另外一種方式,它是一個簡單的JavaScript Runtime.

 

js是由客戶端而產生,Nodejs爲網絡而生

 

Node能作什麼?

  具備複雜邏輯的網站

  局域社交網站的大web的應用

  Web Scoket服務器

  TCP/UDP套接字應用程序

  命令行工具

  交互式終端程序

 

 這有啥拽的,從技術上說就是各類的封裝,並無新大陸呀??!!!!我大微軟C#也能解決,給你個.Net本身體會去吧,後面跟着C/C++,路過…

 說到這點,這兒有一位,絕壁的狠狠的噴了一把, SolidMango 《NODE.JS之我見

總之,各執其詞,很差定論,正如SolidMango所說,堅守己見,不要盲從,看本身怎麼理解吧。

 

Node的優勢

1. 它是一個JavaScript運行環境 (Nodejs採用C++語言編寫而成)
2. 依賴於瀏覽器V8引擎進行代碼解釋

3. 事件驅動

4. 非阻塞

5. 異步I/O

6. 輕量、可伸縮,適於實時數據交互應用

7. 單進程,單線程

 

    Node.Js最大特性是採用異步式I/O與事件驅動的架構設計對於高併發的解決方案,傳統的架構是多線程模型,也就是每一個業務邏輯提供一個系統線程,經過系統線程切換來彌補同步式I/O調用時的時間開銷.

    Node.Js採用的是單線程模型,在執行過程當中會維護一個事件隊列程序在執行時在進入事件循環等待下一個事件的到來。

 

 累了,困了,來個小demo緩解一下----

  ps 我學習是在windows上開發,固然*nix會更好

  Nodejs安裝。。。。此處略去n千字…

  驗證是否安裝成功:運行cmd,輸入  node –v

  

  順帶着把版本(v6.2.0)也檢查了一下,哈哈哈… 好好雞賊了一把

  我用Visual Studio Code開發Nodejs,固然也有蠻多不錯的的IDE:webstorm,notepad++ ,sublime,Eclipse等等

 

一、新建hello.js,裏面寫入

     console.log(' Hello World ');

   保存格式utf-8。存放在d:\NodeJs\demo\hello.js

二、運行cmd命令

    cmd ——》 D:  ——》cd nodejs  ——》cd demo ——》node hello.js

 

還有另一種方式

1. 運行cmd,輸入node,回車 進入Nodejs的編譯模式

Console.log(‘Hello World’);   

2. 輸出結果:

 

第一行是結果

第二行是返回值

 

ok,再來提高一下逼格

Nodejs較牛逼地方,就是對Http的封裝 (Nodejs其底層已是封裝好的服務器)

建立hello.js文件,裏面寫入

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

 

代碼分析:

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

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

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

瀏覽器運行結果以下:

      當一個request到來時,EventLoop會將這個Listener回調函數放入執行隊列, Nodejs中全部的代碼都是一個一個從執行隊列中拿出來執行的。

    這些執行都是在工做線程上(Event Loop自己能夠認爲在一個獨立的線程中,咱們通常不提這個線程,而將Nodejs稱呼爲一個單線程的執行環境),

     全部的回調都是在一個工做線程上運行。

   EventLoop 指的是計算機系統的一種運行機制。簡單的說就是,在程序中設置兩個線程:一個是負責程序自己的運行,稱爲「主線程」;另外一個負責主線程與其餘進程(主要是I/O操做)的通訊。 也能夠叫 「消息線程」

  開發Nodejs程序,調試的時候,不管修改了那一部分代碼,都須要重啓服務才能生效,這是由於Nodejs只有在第一次引用到某部分的時候纔會去解析腳本,之後都會直接訪問內存,避免重複載入

缺點:提升了效率,卻不利於程序調試

解決方案:supervisor ,會監視對代碼的改動,並自動重啓Node.js

   安裝supervisor:用npm安裝,輸入命令符 npm -g install supervisor 

    ps:必須安裝到全局,不然錯誤命令也會提示安裝到全局

    or:修改全局路徑到當前路徑 npm config set prefix "路徑"

 supervisor server.js     //開始監視server.js

 可是若是出錯,會不停的刷cmd,以及網頁間斷性報錯

 

Node.Js的異步式IO與事件式編程

 Node.js最大的特性就是異步式I/O與事件緊密結合的編程模式。這種模式與傳統的同步式IO線性的編程思路有很大的不一樣,由於控制流很大程度上要靠事件和回調函數來組織,一個邏輯要拆分爲若干個單元格。

 內容:阻塞和線程

  1. 同步式I/O或阻塞式I/O

    線程在執行中若是遇到磁盤讀寫或網絡通訊,一般要耗費較長時間。這時操做系統會剝奪這個線程的CPU控制權,使其暫停執行,同時將資源讓給其餘的工做線程,這種線程調度方式成爲阻塞,當I/O操做完畢時,操做系統將這個線程的阻塞狀態解除,恢復其對CPU的控制權、令其繼續執行。

  2. 異步式I/O或非阻塞式I/O

    針對全部I/O操做不採用阻塞策略,當線程遇到I/O操做時,不會以阻塞的方式等待I/O操做的完成或數據的返回,而只是將I/O請求發送給操做系統,繼續執行下一條語句,當操做系統完成I/O操做時,以事件的形式通知執行I/O操做的線程,線程會在特定時候處理這個事件,爲了處理異步I/O,線程必須有事件循環,不斷的檢查有沒有未處理的事件,依次予以處理。

  3. 非阻塞與阻塞模式區別

    非阻塞模式下,一個線程永遠在執行計算操做,這個線程所使用的CPU核心利用率永遠是100%,IO以事件的方式通知。

    阻塞模式下,多線程每每能提升系統吞吐量,由於一個線程阻塞還有其餘線程在工做,多線程可讓CPU資源不被阻塞中的線程浪費。

    調度:當前一個工做,在5分鐘以後執行

  4. 同步式IO與異步式IO區別

同步式IO(阻塞式)

異步式IO(非阻塞)

利用多線程提供吞吐量

單線程便可實現高吞吐量

經過事件片分割和線程調度利用多核CPU

經過功能劃分利用多核

須要由操做系統調度多線程使用多核CPU

能夠將單線程綁定到單核CPU

難以充分利用CPU資源

能夠充分利用CPU資源

內存軌跡大,數據局部性弱

內存軌跡小,數據局部性強

符合線性的編程思惟

不符合傳統編程思惟

 

  異步式  少了多線程的開銷 不符合傳統編程思惟

  同步式  會執行內存換頁,cpu的緩存會被清空,從新讀取內存

  

Node.js的事件循環機制

   (1) Node.js在何時進入事件循環呢?

     Node.js程序是由事件循環開始,到事件循環結束,全部的邏輯都是事件的回調函數。

  (2) 如何使用自定義事件呢?

     事件的回調函數在執行的過程當中,可能會發出IO請求或直接發射(emit)事件,執行完畢後再返回事件循環。

 

模塊(Module)和包(Package)

  1. 模塊

    不一樣的功能組件,劃分爲不一樣的模塊

    模塊的定義十分簡單,接口也十分簡單。它的意義就是將類聚的方法或變量限定在私有的做用域中,同時支持引入和導出功能以便順暢的連接上下游依賴

  例如:

    var http = require('http')   // 其中http是Node.js的一個核心模塊,經過require函數獲取這個模塊,而後使用其中的對象

 

        Node.js提供了exports和require兩個對象,其中exports是模塊公開的接口,require用於從外部獲取一個模塊的接口,即獲取模塊的exports對象

          一般使用module.exports,由於在exports對象是用過形參的方式傳入的,直接賦值形參會改變形參的引用,單並不能改變做用域外的值

    二、包

        包是在模塊基礎上更深一步的抽象,Node.js的包相似於C/C++的函數庫或者java的類庫,它講某個獨立的功能封裝起來,用於發佈、更新、依賴管理的版本控制。開發了npm來解決包的發佈和獲取需求 

  咱們使用這種方法能夠把文件夾封裝成一個模塊,即所謂的包。包一般是一些模塊的集合,在模塊的基礎上提供了更高層的抽象,至關於提供了一些固定接口的函數庫,經過定製package.json,咱們能夠建立更復雜、更完善、更符合規範的包用於發佈。

 

文件操做

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

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

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

var fs = require('fs');
 1.1. 讀取文件 
var fs = require('fs');
1.1.1、 fs.readFile(filename,[encoding],[callback(error,data)])
fs.readFile('book.txt', 'utf-8', (err, data) => {
if (err) {
throw err;
}
console.log(data);

1.1.2、 fs.readFileSync(filename,[encoding])
try {
var data = fs.readFileSync('book.txt', 'utf-8');
console.log(data);
} catch (e) {
throw e; //文件不存在,或者權限錯誤
}

1.1.3、 fs.createReadStream(filename,[options])
var stream = fs.createReadStream('book.txt');
var data = '';
stream.on('data', (trunk) => {
data += trunk;
});
stream.on('end', () => {
console.log(data);
});

1.1.4、 readLine
var readline = require('readline');
var fs = require('fs');
var rl = readline.createInterface({
input: fs.createReadStream('book.txt')
});
rl.on('line', (line) => {
console.log('Line from file:' + line);
})

1.2、文件寫入
1.2.一、 fs.writeFile(filename, [callback(error)]) //若是文件不存在,會自動建立
fs.writeFile('name.txt', 'I am the man', (error) => {
if(error){ 
console.log(error);
} 
})

1.2.2、fs.writeFileSync(file,[data])
try {
fs.writeFileSync('timer.txt', 'JesseFu is the best');
} catch (e) {
console.log(e);
}

1.2.3、fs.createWriteStream(path[,option])
var streamWrite = fs.createWriteStream('fuguoliang.txt');
streamWrite.write('fuguoliang\r\n', (error) => {
console.log(error);
});

1.2.四、fs.appendFile(file,data[,options],callback(err)) //追加文本
setInterval(() => {
fs.appendFile('fuguoliang.txt', '\r\n ----Jesse ' + new Date().getSeconds());
}, 1000)

1.2.5、fs.appendFileSync(file,data[,options])
setInterval(() => {
fs.appendFileSync('fuguoliang.txt', '\r\n ----what the hell... ' + new Date().getSeconds())
}, 1000)

驗證路徑是否存在
fs.exists(path,callback(isexists))   
fs.existsSync(path) //返回true 或 false

獲取文件信息
fs.stat(path,callback(err,stats))
fs.statSync(path) //返回一個fs.stat實例

移動文件 移動/重命名
fs.rename(oldpath,newpath,callback);
fs.renameSync(oldpath,newpath)

刪除文件 永久刪除/
fs.unlink(path,callback(err)); 
fs.unlinkSync(path);

建立一個目錄 (重名會報錯)
fs.mkdir(path[,model],callback)
fs.mkdirSync(path[,model]);

刪除一個空目錄
fs.rmdir(path,callback);
fs.remdirSync(path);

讀取一個目錄 以數組形式展示
fs.readdir(path,callback(err,files))
fs.readdirSync(path); //返回files

 

 

  不容易啊,客官能堅持看完,看來閣下也是性情中人啊。不過在這兒囉嗦了半天,也只能簡單瞭解,至於要更好的玩轉Nodejs還須要更多的學習交流。

言有盡而意無窮,於此,結束Nodejs的初次見面,印象不錯哦,客官有沒有觸到G點我不知道,我是會一直作下去

專業,由於專一

但願個人這篇筆記可以對客官有幫助,不勝榮幸,有好東西要分享一下嘍,多多指教 [抱拳]

 

推薦幾個學習Nodejs的網址:
  http://nodejs.org/   

      http://cnodejs.org/  

      http://www.oschina.net/p/nodejs/  

  http://www.ibm.com/developerworks/cn/opensource/os-nodejs/index.html

相關文章
相關標籤/搜索