以前學習C、OC、Swift、H5的時候都沒有留下痕跡,心里甚是遺憾,最近用Nodejs參與了一個web開發,果斷留個紀念,供日后瞻仰。。。
菜鳥教程:http://www.runoob.com/nodejs/nodejs-install-setup.html
Github:https://github.com/Zyj163/Node.JS_learning(筆記,非demo)
環境配置:
方式一:http://nodejs.org下載安裝(我用的這個)
方式二:使用終端(網上介紹的,沒實驗。。。)
1.安裝home-brew
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)
2.安裝node
brew install node
當安裝Node時會同時安裝npm,npm是Node開發包管理器,用法省略。。。
使用:
先來一個Hello World
創建一個helloWorld.js的文件(我用的編輯器是webStorm)
var http = require('http');
http.createServer(function(req,res){
// 發送 HTTP 頭部
// HTTP 狀態值: 200 : OK
// 內容類型: text/plain
? ? ? ? res.writeHead(200, { 'Content-Type': 'text/plain' });
// 發送響應數據 "Hello World"
? ? ? ? res.end('Hello world!');
}).listen(3000);
console.log('Server started on localhost:3000; press Ctrl-C to terminate....');
打開終端,cd到當前目錄,node hello World.js,然后打開瀏覽器訪問http://localhost:3000即可
推薦一個好東西sudo npm install -g supervisor,cd到當前目錄supervisor helloWorld.js,這樣就不需要每次修改后臺代碼后,重啟服務了,退出Ctrl+c
Node.js 是單進程單線程應用程序,但是通過事件和回調支持并發,所以性能非常高。Node 所有 API 都支持回調函數。
Node.js 的每一個 API 都是異步的,并作為一個獨立線程運行,使用異步函數調用,并處理并發。
Node.js 基本上所有的事件機制都是用設計模式中觀察者模式實現。
Node.js 單線程類似進入一個while(true)的事件循環,直到沒有事件觀察者退出,每個異步事件都生成一個事件觀察者,如果有事件發生就調用該回調函數.
Node.js 使用事件驅動模型,當web server接收到請求,就把它關閉然后進行處理,然后去服務下一個web請求。當這個請求完成,它被放回處理隊列,當到達隊列開頭,這個結果被返回給用戶。引用runoob中的一張圖
EventEmitter
Node.js 有多個內置的事件,我們可以通過引入 events 模塊,并通過實例化 EventEmitter 類來綁定和監聽事件
// 引入 events 模塊
var events = require('events');
// 創建 eventEmitter 對象
var eventEmitter = new events.EventEmitter();
// 綁定事件及事件的處理程序
eventEmitter.on('eventName', eventHandler);
// 觸發事件
eventEmitter.emit('eventName','arg1','arg2');
//移除指定事件的一個已經注冊的監聽器
eventEmitter.removeListener('eventName',eventHandler);
//移除指定事件的所有監聽器
eventEmitter.removeAllListeners('eventName');
EventEmitter 對象如果在實例化時發生錯誤,會觸發 'error' 事件。當添加新的監聽器時,'newListener' 事件會觸發,當監聽器被移除時,'removeListener' 事件被觸發。可以給同一事件創建多個監聽,會被先后調用。
大多數時候我們不會直接使用 EventEmitter,而是在對象中繼承它。 包括 fs、net、 http 在內的,只要是支持事件響應的核心模塊都是 EventEmitter 的子類。
Buffer(緩沖區)
在 Node.js 中,Buffer 類是隨 Node 內核一起發布的核心庫。Buffer 庫為 Node.js 帶來了一種存儲原始數據的方法,可以讓 Node.js 處理二進制數據,每當需要在 Node.js 中處理I/O操作中移動的數據時,就有可能使用 Buffer 庫。原始數據存儲在 Buffer 類的實例中。一個 Buffer 類似于一個整數數組,但它對應于 V8 堆內存之外的一塊原始內存。
//方法 1
//創建長度為 10 字節的 Buffer 實例:
var buf=newBuffer(10);
//方法 2
//通過給定的數組創建 Buffer 實例:
var buf2=newBuffer([10,20,30,40]);
//方法 3
//通過一個字符串來創建 Buffer 實例:
var buf3=newBuffer("www.runoob.com","utf-8");
/*寫入
buf.write(string[, offset[, length]][, encoding])
參數
參數描述如下:
string - 寫入緩沖區的字符串。
offset - 緩沖區開始寫入的索引值,默認為 0 。
length - 寫入的字節數,默認為 buffer.length
encoding - 使用的編碼。默認為 'utf8' 。
* */
var len=buf.write('www.runoob.com');
console.log('寫入字節數:'+len);
/*讀取
buf.toString([encoding[, start[, end]]])
參數
參數描述如下:
encoding - 使用的編碼。默認為 'utf8' 。
start - 指定開始讀取的索引位置,默認為 0。
end - 結束位置,默認為緩沖區的末尾。
* */
var re=buf.toString();
//轉為json對象
var json=buf.toJSON(buf);
//合并buffer
var buf4= Buffer.concat([buf,buf3]);
/*拷貝
buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
參數
參數描述如下:
targetBuffer - 要拷貝的 Buffer 對象。
targetStart - 數字, 可選, 默認: 0
sourceStart - 數字, 可選, 默認: 0
sourceEnd - 數字, 可選, 默認: buffer.length
* */
var buf5=newBuffer(10);
buf5.copy(but);
Stream(流)
Stream 對象都是 EventEmitter 的實例(對http 服務器發起請求的request 對象就是一個 Stream,所以request也有下面的事件)。常用的事件有:
data - 當有數據可讀時觸發。
end - 沒有更多的數據可讀時觸發。
error - 在接收和寫入過程中發生錯誤時觸發。
finish - 所有數據已被寫入到底層系統時觸發。
從流中讀數據:
var fs = require("fs");
var data = '';
// 創建可讀流
var readerStream = fs.createReadStream('input.txt');
// 設置編碼為 utf8。
readerStream.setEncoding('UTF8');
// 處理流事件 --> data, end, and error
readerStream.on('data', function(chunk) {
data += chunk;
});
readerStream.on('end',function(){
console.log(data);
});
readerStream.on('error', function(err){
console.log(err.stack);
});
寫入流:
var fs = require("fs");
var data = '菜鳥教程官網地址:www.runoob.com';
// 創建一個可以寫入的流,寫入到文件 output.txt 中
var writerStream = fs.createWriteStream('output.txt');
// 使用 utf8 編碼寫入數據
writerStream.write(data,'UTF8');
// 標記文件末尾
writerStream.end();
// 處理流事件 --> data, end, and error
writerStream.on('finish', function() {
console.log("寫入完成。");
});
writerStream.on('error', function(err){
console.log(err.stack);
});
console.log("程序執行完畢");
管道流:
var fs= require('fs')
var zlib= require('zlib')
//壓縮
fs.createReadStream('input.txt')
? ?.pipe(zlib.createGzip())
? ?.pipe(fs.createWriteStream('input.zip'))
//解壓
fs.createReadStream('input.zip')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('input.txt'))
模塊系統:
1、提供函數:
定義:
exports.world = function() {}
使用:
var use = require('./world');
use.world();
2、提供對象:
定義:(fuc外面的東西可以理解為私有的,里面的是公開的)
function Hello() {
? ? ? ? ? ? ? var name;
? ? ? ? ? ? ? this.setName = function(thyName) {
? ? ? ? ? ? ? ? ? ? ? ? ?name = thyName;
? ? ? ? ? ? ? };
? ? ? ? ? ? ? this.sayHello = function() {
? ? ? ? ? ? ? ? ? ? ? ? console.log('Hello ' + name);
? ? ? ? ? ? ? };
};
module.exports = Hello;
使用:
var Hello = require('./hello');
hello = new Hello();
hello.setName('BYVoid');
hello.sayHello();
路由:
解析URL,引用url和querystring模塊
全局對象與全局變量:
__filename 表示當前正在執行的腳本的文件名。它將輸出文件所在位置的絕對路徑,且和命令行參數所指定的文件名不一定相同。 如果在模塊中,返回的值是模塊文件的路徑。
__dirname 表示當前執行腳本所在的目錄。
process.memoryUsage() 輸出內存使用情況
常用工具:
util.inherits(constructor, superConstructor)是一個實現對象間原型繼承 的函數。JavaScript 的面向對象特性是基于原型的,與常見的基于類的不同。JavaScript 沒有 提供對象繼承的語言級別特性,而是通過原型復制來實現的。
var util= require('util');
functionBase(){
//不能繼承
this.name='base';
this.base=1991;
this.sayHello=function(){
console.log('hello'+this.name);
}
}
//可以被繼承
Base.prototype.showName=function(){
console.log(this.name);
};
functionSub(){
this.name='sub';
//Sub 僅僅繼承了Base 在原型中定義的函數,而構造函數內部創造的 base 屬 性和 sayHello 函數都沒有被 Sub 繼承。
}
util.inherits(Sub,Base);
varobjBase=newBase();
objBase.showName();
objBase.sayHello();
console.log(objBase);
varobjSub=newSub();
objSub.showName();
console.log(objSub);
util.inspect(object,[showHidden],[depth],[colors])是一個將任意對象轉換 為字符串的方法,通常用于調試和錯誤輸出。它至少接受一個參數 object,即要轉換的對象。
更多詳情可以訪問 http://nodejs.org/api/util.html 了解詳細內容
可以使用typeof some ==='function' 做類型判斷
文件系統:
應該很多都需要知道,沒必要截了http://www.runoob.com/nodejs/nodejs-fs.html
知道這些基礎知識差不多就可以進行下一個目標express了,這個才是重點!!