標籤:
console是node.js提供的控制台對象,包含了向標準輸出寫入的操作,如console.log、console.error等。
console.log是最常用的輸出指令,可以接受任意個參數,支援%d、%s變數引用。
REPL模式
運行無參數的node會啟動,出現 > 輸入指令。
建立HTTP伺服器
運行 node 檔案名稱.js ,訪問http://127.0.0.1:3000
調用http模組,對所有HTTP請求回覆同樣的內容並監聽3000連接埠。listen函數中建立了事件監聽器,Node.js不會退出事件迴圈,直到按下Ctrl+C才會結束。
var http = require(‘http‘);http.createServer(function(req, res) { res.writeHead(200, {‘Content-tyle‘: ‘text/html‘}); res.write(‘<h1>Node.js</h1>‘); res.end(‘<p>Hello world</p>‘);}).listen(3000);console.log("HTTP server is listening at port 3000");
同步I/O 阻塞式I/O
線程在執行中如果遇到磁碟讀寫或網路通訊(統稱I/O操作),作業系統會剝奪這個線程的CPU控制權,使其暫停執行,同時將資源讓給其他的背景工作執行緒。
當I/O操作完畢,作業系統將這個線程的阻塞狀態解除,恢複其對CPU的控制權,令其繼續執行。
var fs = require(‘fs‘);var data = fs.readFileSync(‘file.txt‘, ‘utf-8‘);console.log(data);console.log(‘end.‘);//運行結果nimaend.
非同步I/O 非阻塞式I/O
當線程遇到I/O操作時,將I/O請求發給作業系統,繼續執行下一條語句。作業系統完成I/O操作時,以事件的形式通知執行I/O操作的線程,線程會在特定時候處理這個事件。為了處理非同步I/O,線程必須有事件迴圈,不斷地檢查有沒有未處理得事件,依次予以處理。
var fs = require(‘fs‘);fs.readFile(‘file.txt‘,‘utf-8‘,function(err,data){ if(err){ console.error(err); } else { console.log(data); }});console.log(‘end.‘);//運行結果end.nima
fs.readFile調用時所做的工作知識將非同步式I/O請求發送給作業系統,然後立即返回並執行後面的語句,執行完以後進入事件迴圈監聽事件。當fs接收到I/O請求完成的事件時,事件迴圈會主動調用回呼函數以完成後續工作。
並不是所有API都有同步和非同步版本,Node.js不鼓勵使用同步I/O。
事件
事件是由EventEmitter對象提供。
var EventEmitter = require(‘events‘).EventEmitter;var event = new EventEmitter();event.on(‘some_event‘, function(){ console.log(‘some_event occured.‘);});setTimeout(function () { event.emit(‘some_event‘);}, 1000);//一秒後輸出 some_event occured.
event對象註冊了事件some_event的一個監聽器,通過setTimeout在1000毫秒以後向event對象發送事件some_event,此時會調用some_event的監聽器。
模組和包
exports是模組公開的介面,require用於從外部擷取一個模組的介面,即所擷取模組的exports對象。
覆蓋exports
function Hello() {
};
exports.Hello = Hello;
在其他檔案需要通過 require(‘./檔案名稱‘).hello來擷取Hello對象。
module.exports = Hello;
可以直接獲得這個對象 require(‘./檔案名稱‘)。
在外部參考該模組時,其介面對象就是要輸出的Hello對象本身,而不是原先的exports。
exports是module.exports的一個引用,只是為了用起來方便。當你想輸出的是例如建構函式這樣的單個項目,那麼需要使用module.exports。
不可以通過對exports直接賦值代替對module.exports賦值。exports實際上只是一個和module.exports指向同一個對象的變數,它本身在模組指向結束後釋放,但module不會,因此只能通過module.exports來改變提供者。
建立包
node.js在調用某個包時,會先檢查包中package.json檔案的main欄位,將其作為包的介面模組,如果package.json欄位不存在,會嘗試尋找index.js或index.node作為包的介面。
npm
擷取一個包
npm i/install package_name
預設使用install命令是採用本地模式,安裝後放置在目前的目錄的node_modules子目錄下。node.js的require在載入模組時嘗試搜尋node_modules子目錄,因此使用npm本地模式安裝的包可以直接被引用。
全域模式
npm i/install package_name -g
多數時候並不是因為許多程式都有可能用到它,為了減少多重副本而使用全域模式,而是因為本地模式不會註冊path環境變數。npm本地模式僅僅是把包安裝到node_modules子目錄下,其中的bin目錄沒有包含在path環境變數,不能直接在命令列中調用。全域模式安裝時npm將包安裝到系統目錄,package.json檔案中bin欄位包含的檔案會被連結到/usr/local/bin/。/usr/local/bin/是在path環境變數預設定義的。
| 模式 |
可通過require使用 |
註冊path |
| 本地模式 |
是 |
否 |
| 全域模式 |
否 |
是 |
我們要把某個包作為工程運行時的一部分通過本地模式擷取,要在命令列使用則通過全域模式安裝。
發布包
使用npm init根據互動式會打產生package.json
建立index.js作為包的介面。
使用npm adduser建立帳號,完成後可使用npm whoami 測試是否取得了帳號。
發布:在package.json所在目錄運行npm publish,訪問http://search.npmjs.org/能找到發布的包。
更新:在package.json檔案中修改version,重新使用npm publish命令。
取消:npm unpublish
node.js入門