node.js是創建在谷歌Chrome的JavaScript引擎(v8)的web應用程序框架。node
node.js 自帶的運行環境可在JavaScript腳本的基礎上解釋和執行。這個運行是運行在瀏覽器之外的任何機器上執行JavaScript代碼。因此也能夠在服務端運行,Node.js還提供了各類豐富的JavaScript模塊庫,它極大簡化了使用Node.js來擴展Web應用程序的研究與開發。web
Node.js庫的異步和事件驅動的API所有都是異步就是非阻塞。它主要是指基於Node.js的服務器不會等待API返回的數據。服務器移動到下一個API調用,Node.js發生的事件通知機制後有助於服務器得到從以前的API調用的響應。express
很是快的內置谷歌Chrome的V8 JavaScript引擎,Node.js庫代碼執行是很是快的。npm
單線程但高度可擴展 - Node.js使用具備循環事件單線程模型。編程
沒有緩衝 - Node.js的應用歷來不使用緩衝任何數據。這些應用只是輸出數據在塊中。json
適合:I/O 綁定應用程序,數據流應用,數據密集型實時應用(DIRT),JSON API的應用程序,單頁面應用。數組
不適合:CPU密集型應用。瀏覽器
下載安裝完成後,經過cmd啓動執行文件。服務器
node -v 查看當前node版本。網絡
經過編寫js文件,而後再cmd當前目錄運行文件。
1 var http = require('http'); 2 http.createServer(function(req,res){ 3 res.writeHead(200,{'Content-Type':'text/plain'}); 4 res.end('Hello World\n'); 5 }).listen(1337,'127.0.0.1'); 6 console.log('Server running at http://127.0.0.1:1337/');
執行當前文件目錄執行node hello.js
起一個簡單的服務,在瀏覽器可輸入地址,後顯示
npm 表示節點程序包管理器。是Node.js包/模塊的在線軟件倉庫;能夠在命令行實用程序安裝包,做爲Node.js版本管理和依賴包管理。
npm -v 查看當前npm版本。(通常安裝node.js自帶npm)-g 表示資源包全局安裝。
npm install express (一個實用的web框架)
npm ls 查詢
package.json是存在於任何Node應用程序/模塊的根目錄,並用於定義一個包的屬性。
回調是一種異步至關於一個函數。回調函數被調用在完成既定任務。Node大量使用了回調。Node全部的API寫的都是支持回調的這樣一種方式。例如,一個函數讀取一個文件可能開始讀取文件,並當即返回控制到執行環境 使得下一個指令能夠立刻被執行。一旦文件 I/O 完成,它會調用回調函數,同時傳遞迴調函數,該文件做爲參數的內容。所以不會有堵塞或等待文件I/O。這使得Node.js高度可擴展,所以能夠處理大量的請求,而無需等待任何函數來返回結果。
阻塞代碼/非阻塞代碼。
1 var fs = require('fs'); 2 3 fs.readFile('text.txt',function(err,data){ 4 if(err) return console.log(err); 5 console.log(data.toString()); 6 }) 7 console.log("end!!");
Node JS是單線程應用程序,但它經過事件和回調的概念,支持併發。NodeJS的每個API都是異步的,做爲一個單獨的線程,它使用異步函數調用來維護併發。Node使用觀察者模式。Node線程保持一個事件循環,每當任何任務完成後獲得結果,它觸發通知事件偵聽函數來執行相應的事件。
Node.js使用大量事件,這也是爲何Node.js相對於其餘相似技術比較快的緣由之一。當Node啓動其服務器,就能夠簡單地初始化其變量,聲明函數,而後等待事件的發生。
1 // 聲明須要事件 2 var events = require('events'); 3 // 建立事件對象 4 var eventEmitter = new events.EventEmitter(); 5 // 聲明觸發事件執行的函數 6 var connected = function connected() { 7 console.log('connection succesful!') 8 eventEmitter.emit('data_received.'); 9 } 10 // 綁定事件 11 eventEmitter.on("connection",connected); 12 eventEmitter.on("data_received",function(){ 13 console.log('data received succesfully.'); 14 }); 15 // 事件觸發 16 eventEmitter.emit('connection'); 17 console.log('code end!');
錯誤處理:
1 var fs = require("fs"); 2 3 fs.readFile('test.txt', function (err, data) { 4 if (err){ 5 console.log(err.stack); 6 return; 7 } 8 console.log(data.toString()); 9 }); 10 console.log("Program Ended");
事件監聽的添加移除與觸發
1 // 須要事件 2 var events = require('events'); 3 // 建立事件對象 4 var eventEmitter = new events.EventEmitter(); 5 // 事件1 6 var listner1 = function listner1() { 7 console.log('this is 11111'); 8 } 9 // 事件2 10 var listner2 = function listner2() { 11 console.log('this is 22222'); 12 } 13 // 事件監聽addListener與on效果相同 14 eventEmitter.addListener('connection',listner1); 15 eventEmitter.on('connection',listner2); 16 // 另外一種寫法 17 var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection'); 18 console.log(eventListeners + " Listner(s) listening to connection event"); 19 // 觸發事件 20 eventEmitter.emit('connection'); 21 // 移除事件監聽 22 eventEmitter.removeListener('connection', listner1); 23 console.log("Listner111 will not listen now. removeListener"); 24 // 再觸發事件 25 eventEmitter.emit('connection'); 26 // 添加事件監聽 27 eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection'); 28 console.log(eventListeners + " Listner(s) listening to connection event"); 29 30 console.log("Program Ended.");
Buffer類是一個全局類,能夠在應用程序,無需導入緩衝模塊進行訪問。緩衝區是一種整數數組並對應於原始存儲器V8堆之外分配。 緩衝區不能調整大小。
在 ECMAScript 2015
引入 TypedArray
以前,JavaScript 語言沒有讀取或操做二進制數據流的機制。 Buffer
類被引入做爲 Node.js API 的一部分,使其能夠在 TCP 流或文件系統操做等場景中處理二進制數據流。
TypedArray
現已被添加進 ES6 中,Buffer
類以一種更優化、更適合 Node.js 用例的方式實現了 Uint8Array
API。
1 var buffer = new Buffer(26); 2 console.log("buffer length: " + buffer.length); 3 var data = "YiiBai.com"; 4 5 buffer.write(data); 6 console.log(data + ": " + data.length + " characters, " + Buffer.byteLength(data, 'utf8') + " bytes"); 7 8 var buffer1 = buffer.slice(0,14); 9 console.log("buffer1 length: " + buffer1.length); 10 console.log("buffer1 content: " + buffer1.toString()); 11 12 for (var i = 0 ; i < 26 ; i++) { 13 buffer[i] = i + 97; // 97 is ASCII a 14 } 15 console.log("buffer content: " + buffer.toString('ascii')); 16 17 var buffer2 = new Buffer(4); 18 19 buffer2[0] = 0x3; 20 buffer2[1] = 0x4; 21 buffer2[2] = 0x23; 22 buffer2[3] = 0x42; 23 24 //reading from buffer 25 console.log(buffer2.readUInt16BE(0)); 26 console.log(buffer2.readUInt16LE(0)); 27 console.log(buffer2.readUInt16BE(1)); 28 console.log(buffer2.readUInt16LE(1)); 29 console.log(buffer2.readUInt16BE(2)); 30 console.log(buffer2.readUInt16LE(2)); 31 32 var buffer3 = new Buffer(4); 33 buffer3.writeUInt16BE(0xdead, 0); 34 buffer3.writeUInt16BE(0xbeef, 2); 35 console.log(buffer3); 36 37 buffer3.writeUInt16LE(0xdead, 0); 38 buffer3.writeUInt16LE(0xbeef, 2); 39 40 console.log(buffer3); 41 42 //convert to a JSON Object 43 var json = buffer3.toJSON(); 44 console.log("JSON Representation : "); 45 console.log(json); 46 47 //Get a buffer from JSON Object 48 var buffer6 = new Buffer(json); 49 console.log(buffer6); 50 51 //copy a buffer 52 var buffer4 = new Buffer(26); 53 buffer.copy(buffer4); 54 console.log("buffer4 content: " + buffer4.toString()); 55 56 //concatenate a buffer 57 var buffer5 = Buffer.concat([buffer,buffer4]); 58 console.log("buffer5 content: " + buffer5.toString());
數據流是從源數據讀取或寫入數據到目標對象以。在節點中,有四種類型的流:
Readable - 數據流,其是用於讀操做
Writable - 數據流,用在寫操做
Duplex - 數據流,其能夠用於讀取和寫入操做
Transform - 雙相類型流,輸出基於輸入進行計算
每種類型的流是EventEmitter,而且一次引起幾個事件。例如,一些經常使用的事件是:
data - 當有數據可讀取時觸發此事件
end - 當沒有更多的數據讀取時觸發此事件
error - 當有錯誤或接收數據寫入時觸發此事件
finish - 當全部數據已刷新到底層系統時觸發此事件
1 var fs = require("fs"); 2 var data = ''; 3 //create a readable stream 4 var readerStream = fs.createReadStream('text.txt'); 5 6 //set the encoding to be utf8. 7 readerStream.setEncoding('UTF8'); 8 9 //handle stream events 10 readerStream.on('data', function(chunk) { 11 data += chunk; 12 }); 13 14 readerStream.on('end',function(){ 15 console.log(data); 16 }); 17 18 readerStream.on('error', function(err){ 19 console.log(err.stack); 20 }); 21 console.log("-------------Program Ended---------------");
1 var fs = require("fs"); 2 var data = 'Yiibai.Com'; 3 //create a writable stream 4 var writerStream = fs.createWriteStream('text1.txt'); 5 6 //write the data to stream 7 //set the encoding to be utf8. 8 writerStream.write(data,'UTF8'); 9 10 //mark the end of file 11 writerStream.end(); 12 13 //handle stream events 14 writerStream.on('finish', function() { 15 console.log("Write completed."); 16 }); 17 18 writerStream.on('error', function(err){ 19 console.log(err.stack); 20 }); 21 console.log("--------------Program Ended---------------");
每個fs模塊的方法都有同步和異步形式。異步方法接受一個最後的參數爲完成回調函數,而回調函數的第一個參數是錯誤。它優選使用異步方法來代替同步方法,前者從未阻塞程序執行,然後者則會阻塞。
1 var fs = require("fs"); 2 var buffer = new Buffer(1024); 3 4 //Example: Opening File打開文件 5 function openFile(){ 6 console.log("\nOpen file--------"); 7 fs.open('test.txt', 'r+', function(err,fd) { 8 if (err) console.log(err.stack); 9 console.log("File opened"); 10 }); 11 } 12 13 //Example: Getting File Info 統計信息 14 function getStats(){ 15 console.log("\nGetting File Info---------"); 16 fs.stat('test.txt', function (err, stats) { 17 if (err) console.log(err.stack); 18 console.log(stats); 19 console.log("isFile ? "+stats.isFile()); 20 console.log("isDirectory ? "+stats.isDirectory()); 21 }); 22 } 23 24 //Example: Writing File 寫 25 function writeFile(){ 26 console.log("\nWrite file-----------"); 27 fs.open('test2.txt', 'w+', function(err,fd) { 28 var data = "Yiibai.com - Simply Easy Learning!"; 29 buffer.write(data); 30 31 fs.write(fd, buffer,0,data.length,0,function(err, bytes){ 32 if (err) console.log(err.stack); 33 console.log(bytes + " written!"); 34 }); 35 }); 36 } 37 38 //Example: Read File 讀取 39 function readFile(){ 40 console.log("\nRead file----------"); 41 fs.open('test1.txt', 'r+', function(err,fd) { 42 if (err) console.log(err.stack); 43 fs.read(fd, buffer,0,buffer.length,0,function(err, bytes){ 44 if (err) console.log(err.stack); 45 console.log(bytes + " read!"); 46 if(bytes > 0){ 47 console.log(buffer.slice(0,bytes).toString()); 48 } 49 }); 50 }); 51 } 52 // 關閉 53 function closeFile(){ 54 console.log("\nClose file-------------"); 55 fs.open('test.txt', 'r+', function(err,fd) { 56 if (err) console.log(err.stack); 57 fs.close(fd,function(){ 58 if (err) console.log(err.stack); 59 console.log("File closed!"); 60 }); 61 }); 62 } 63 // 刪除 64 function deleteFile(){ 65 console.log("\nDelete file-----------"); 66 fs.open('test1.txt', 'r+', function(err,fd) { 67 fs.unlink('test1.txt', function(err) { 68 if (err) console.log(err.stack); 69 console.log("File deleted!"); 70 }); 71 }); 72 } 73 // 縮短,刪節? 74 function truncateFile(){ 75 console.log("\nTruncate file------------"); 76 fs.open('test.txt', 'r+', function(err,fd) { 77 fs.ftruncate(fd, function(err) { 78 if (err) console.log(err.stack); 79 console.log("File truncated!"); 80 }); 81 }); 82 } 83 84 function createDirectory(){ 85 console.log("\nCreate Directory--------------"); 86 fs.mkdir('test',function(err){ 87 if(!err){ 88 console.log("Directory created!"); 89 } 90 if(err && err.code === 'EEXIST'){ 91 console.log("Directory exists!"); 92 } else if (err) { 93 console.log(err.stack); 94 } 95 }); 96 } 97 // 移除 98 function removeDirectory(){ 99 console.log("\nRemove Directory---------------"); 100 fs.rmdir('test',function(err){ 101 if(!err){ 102 console.log("Directory removed!"); 103 } 104 if (err) { 105 console.log("Directory do not exist!"); 106 } 107 }); 108 } 109 // 監聽 110 function watchFile(){ 111 fs.watch('test.txt', function (event, filename) { 112 console.log('event is: ' + event); 113 }); 114 } 115 116 //Opening file 117 openFile(); 118 119 //Writing File 120 writeFile(); 121 122 //Reading File 123 readFile(); 124 125 //Closing Files 126 closeFile(); 127 128 //Getting file information 129 getStats(); 130 131 //Deleting Files 132 deleteFile(); 133 134 //Truncating Files 135 truncateFile(); 136 137 //Creating Directories 138 createDirectory(); 139 140 //Removing Directories 141 removeDirectory(); 142 143 //Watching File Changes 144 watchFile();
process 是一個全局性對象,並用於表示Node進程。
Process(進程)是一個eventEmitter,而且它發出下列事件
Process(進程)提供了許多有用的特性,以更好地控制系統的相互做用。
Process(進程)提供了許多有用的方法,以更好的控制系統的相互做用。
1 var util = require('util'); 2 3 //printing to console 4 process.stdout.write("Hello World!" + "\n"); 5 6 //reading passed parameter 7 process.argv.forEach(function(val, index, array) { 8 console.log(index + ': ' + val); 9 }); 10 11 //executable path 12 console.log(process.execPath); 13 14 //print the current directory 15 console.log('Current directory: ' + process.cwd()); 16 17 //print the process version 18 console.log('Current version: ' + process.version); 19 20 //print the memory usage 21 console.log(util.inspect(process.memoryUsage()));
path 模塊用於處理和轉換文件路徑。path模塊可使用如下語法導入。
var path = require("path")
1 var path = require("path"); 2 3 //normalization 4 console.log('normalization : ' + path.normalize('/test/test1//2slashes/1slash/tab/..')); 5 6 //join 7 console.log('joint path : ' + path.join('/test', 'test1', '2slashes/1slash', 'tab', '..')); 8 9 //resolve 10 console.log('resolve : ' + path.resolve('test.js')); 11 12 //extName 13 console.log('ext name : ' + path.extname('test.js'));
net 模塊是用來建立服務器和客戶端。它提供了一個異步網絡包裝。 net模塊可使用如下語法導入。
var net = require("net")
dns 模塊是用來作實際的DNS查找,以及使用底層操做系統的名稱解析功能..它提供了一個異步網絡包裝。dns模塊可使用如下語法導入。
var dns = require("dns")
domain 模塊是用於攔截未處理的錯誤。這些未處理的錯誤可使用內部綁定或外部綁定來攔截。若是錯誤都那麼不處理,那麼Node應用會崩潰。
內部綁定 - 錯誤發生執行代碼是在一個域的run方法。
外部綁定 - 使用它的add方法將錯誤發生明確地加入到域。
domain(域)模塊可使用如下語法導入。
var domain = require("domain")
域模塊的Domain類是用來提供路由錯誤以及未捕獲異常活動域對象的功能。 這是一個EventEmitter的子類。爲了處理它捕獲錯誤,監聽它的錯誤事件。它使用以下的語法建立:
var domain = require("domain"); var domain1 = domain.create();
一點基礎內容,沒深刻研究,瞭解基礎,建立文本服務應用,之後再進行跟深層次的挖掘!!