Nodejs核心模塊
核心模塊時Nodejs的心臟,它由一部分精簡而高效的庫組成,爲Nodejs提供了基本的API。
4.1 全局對象
JS中有一個特殊的對象,成爲全局對象,它及其所有的屬性可以在程序的任何地方進行訪問,即全局變量。在瀏覽器JS中,window是全局對象。而Nodejs中的全局對象則是global,所有的全局變量都是gobal對象的屬性。也就是說,在Nodejs中能直接訪問到的對象通常都是global的屬性,如console(這個我們再熟悉不過了),process等。
在Nodejs中,你永遠也不可能在最外層定義變量,因爲所有的用戶代碼都是屬於當前模塊的,而模塊本身不屬於最外層上下文。換句話說,Nodejs的模塊機制不會讓你有機會污染全局命名空間。
4.1.1 __filename和__dirname
__filename表示當前正在執行的腳本文件名,它將輸出文件所在位置的絕對路徑,且和命令行參數所指定的文件名不一定相同。 如果在模塊中,返回的值是模塊文件的路徑。
__dirname則表示當前執行腳本所在的目錄。
運行下列代碼
console.log(__filename);console.log(__dirname);
輸出結果:
D:\WebStorm 2016.2\WSPro\Node\NodejsCoreModule\globalObject__filename.js
D:\WebStorm 2016.2\WSPro\Node\NodejsCoreModule\globalObject
注意它輸出的是文件的絕對路徑。
4.1.2 console對象
console 用於提供控制檯標準輸出,它是由 Internet Explorer 的 JScript 引擎提供的調試工具,後來逐漸成爲瀏覽器的事實標準。Node.js 沿用了這個標準,提供與習慣行爲一致的 console 對象,用於向標準輸出流(stdout)或標準錯誤流(stderr)輸出字符。
我們在hello world案例中介紹過console的最常見用法:console.log()。下面是console對象的所有方法,我們將選擇幾個常見的進行重點講解:
4.1.2.1 console.log()
讓我們更深入的瞭解一下這個方法:console.log()接收若干個參數:如果沒有參數,則打印一個換行;若只有一個參數,則輸出這個參數的字符串格式;如果有多個參數,則成類似於C語言printf的形式,例如:
console.log("%s:%d","hello",25)
輸出的結果是hello:25。
4.1.2.2 console.info()/console.error()/console.warn()
用法與console.log類似,輸出信息、錯誤、警告消息,在控制檯輸出的字符串的顏色會發生變化或者其前會出現特別標誌,不同的終端執行的效果不一樣。
4.1.2.3 console.time()和console.timeEnd()
這兩個是一對計時器組合,從console.time()開始計時,直到console.timeEnd()計時結束。它們都接收一個參數label,用於相互匹配。最後console.timeEnd()會輸出 label:時間(以毫秒爲單位)。 下面的代碼會讓你對它們的作用一目瞭然:
console.time("hello");
for(var i = 0;i<10086;i++){
}
console.timeEnd("hello");
輸出:
hello:1ms**(注:時間會因機器及其狀態不同而不同)**
4.1.2.4 console.trace()
向標準錯誤流輸出當前調用棧,console.trace(“I am tracing”)。運行結果:
這個大概是比較高級的程序設計師纔會用到的。
4.1.3 process
process用於描述當前Nodejs進程的狀態,提供了一個與操作系統的簡單接口,通常你在寫本地命令行程序的時候少不了要和它打交道。
4.1.3.1 process進程事件
通過process在進程上註冊相應的事件(更像是複寫nodejs爲我們註冊好了的事件),在進程執行到的某一個時間點(比如進程將要結束、發生異常時等)將自動觸發這些事件。下面的代碼將幫助您理解process進程事件:
process.on("exit",function (code) {
console.log("程序已經執行完畢,退出碼"+code);
throw new Error("系統錯誤")
});
process.on("uncaughtException", function () {
console.log("錯誤已處理");
});
console.log("程序執行完畢");
運行結果:
程序執行完畢
程序已執行完畢,退出碼:0
錯誤已處理
從結果可以看出我們的程序會在執行完process綁定的事件的所有內容後結束。爲process綁定uncaughtException可以有效的防治遇到未處理錯誤時打印堆棧跟蹤信息並退出程序的默認行爲出現。但注意,這種事件只在process.on的監聽器的回調函數裏其作用;在全局發生的錯誤不會被它處理
括展:
錯誤狀態碼。上面的代碼中我們輸出了code,如果程序正常執行或者異常被捕獲,則code爲0,否則code則爲一個數字(1—12)。下面是錯誤狀態碼及其對應的錯誤的表格:
4.1.3.2 process的屬性
process提供了很多有用的屬性,方便我們更好的與系統交互:
(1)標準輸入流和標準輸出流
// 從控制檯輸入信息
process.stdin.resume();
// 獲得控制檯的信息
process.stdin.on('data', function (data) {
process.stdout.write('read from console: ' + data.toString());
});
這段代碼的作用就是從控制檯輸入一句話,然後程序會將你的之句話打印出來。這裏要注意,獲得的data默認是以二進制的形式讀取,值是一個Buffer對象:<Buffer e5 a4 a7 e5 ae b6 e5 a5 bd>
所以要用toString將其轉化爲字符串。
(2)其他常用屬性
// 通過參數讀取
process.argv.forEach(function(val, index, array) {
console.log(index + ': ' + val);
});
// 獲取執行路局(即node.exe的路徑)
console.log(process.execPath);
// 平臺信息
console.log(process.platform);
輸出:
0: D:\node\node.exe
1: D:\WebStorm 2016.2\WSPro\Node\NodejsCoreModule\globalObject\process\processCharactor.js
D:\node\node.exe
win32
4.1.3.3 process成員方法
成員方法彙總表如下所示,按照老規矩,還是挑選幾個重點的說:
(1)process.nextTick(callback)
這個方法爲事件循環設置一項任務,Nodejs會在下次事件循環響應時調用callback。我們之前討論過,Nodejs適合做IO密集型的應用,而不是計算密集型的應用,因爲Nodejs只有一個線程,在任意時刻只有一個事件在執行。如果某個事件佔用大量的CPU時間,執行時間循環的下一個事件就需要等待很久,因此Nodejs的一個原則就是儘量縮短每個事件的執行時間。process.nextTick()可以把複雜的工作拆散,變成一個個較小的事件。
function doSomething() {
console.log("world");
process.nextTick(function () {
for(var i = 0; i<999999; i++){
}
console.log("end")
});
}
doSomething();
console.log("hello");
如上代碼,我們把循環放到了事件隊列的最後面,所以輸出:
hello
world
end
(2)其他重要方法
// 輸出當前目錄
console.log('當前目錄: ' + process.cwd());
// 輸出內存使用情況
console.log(process.memoryUsage());
// 以指定的狀態碼結束進程
process.exit(4);
運行結果:
當前目錄: d:\WebStorm 2016.2\WSPro\Node\NodejsCoreModule\globalObject\process
{ rss: 17637376, heapTotal: 7409232, heapUsed: 3881296 }
[ 448465, 577789534 ]
這裏注意,與__filename不同,process.cwd()是指的運行node的工作目錄,可以使用 cd /d 對工作目錄進行修改。