W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
process對象是Node的一個全局對象,提供當(dāng)前node進(jìn)程的信息。它可以在腳本的任意位置使用,不必通過require命令加載。該對象部署了EventEmitter接口。
通過process對象,可以獲知當(dāng)前進(jìn)程的很多信息。
進(jìn)程退出時,會返回一個整數(shù)值,表示退出時的狀態(tài)。這個整數(shù)值就叫做退出碼。下面是常見的Node進(jìn)程退出碼。
process對象提供一系列屬性,用于返回系統(tǒng)信息。
/usr/local
,則node的執(zhí)行文件目錄為/usr/local/bin/node
。下面是主要屬性的介紹。
以下屬性指向系統(tǒng)IO。
(1)stdout
stdout屬性指向標(biāo)準(zhǔn)輸出(文件描述符1)。它的write方法等同于console.log,可用在標(biāo)準(zhǔn)輸出向用戶顯示內(nèi)容。
console.log = function(d) {
process.stdout.write(d + '\n');
};
下面代碼表示將一個文件導(dǎo)向標(biāo)準(zhǔn)輸出。
var fs = require('fs');
fs.createReadStream('wow.txt')
.pipe(process.stdout);
上面代碼中,由于process.stdout和process.stdin與其他進(jìn)程的通信,都是流(stream)形式,所以必須通過pipe管道命令中介。
var fs = require('fs');
var zlib = require('zlib');
fs.createReadStream('wow.txt')
.pipe(zlib.createGzip())
.pipe(process.stdout);
上面代碼通過pipe方法,先將文件數(shù)據(jù)壓縮,然后再導(dǎo)向標(biāo)準(zhǔn)輸出。
(2)stdin
stdin代表標(biāo)準(zhǔn)輸入(文件描述符0)。
process.stdin.pipe(process.stdout)
上面代碼表示將標(biāo)準(zhǔn)輸入導(dǎo)向標(biāo)準(zhǔn)輸出。
由于stdin和stdout都部署了stream接口,所以可以使用stream接口的方法。
process.stdin.setEncoding('utf8');
process.stdin.on('readable', function() {
var chunk = process.stdin.read();
if (chunk !== null) {
process.stdout.write('data: ' + chunk);
}
});
process.stdin.on('end', function() {
process.stdout.write('end');
});
(3)stderr
stderr屬性指向標(biāo)準(zhǔn)錯誤(文件描述符2)。
argv屬性返回一個數(shù)組,由命令行執(zhí)行腳本時的各個參數(shù)組成。它的第一個成員總是node,第二個成員是腳本文件名,其余成員是腳本文件的參數(shù)。
請看下面的例子,新建一個腳本文件argv.js。
// argv.js
console.log("argv: ",process.argv);
在命令行下調(diào)用這個腳本,會得到以下結(jié)果。
$ node argv.js a b c
[ 'node', '/path/to/argv.js', 'a', 'b', 'c' ]
上面代碼表示,argv返回數(shù)組的成員依次是命令行的各個部分,真正的參數(shù)實(shí)際上是從process.argv[2]
開始。要得到真正的參數(shù)部分,可以把a(bǔ)rgv.js改寫成下面這樣。
// argv.js
var myArgs = process.argv.slice(2);
console.log(myArgs);
execPath屬性返回執(zhí)行當(dāng)前腳本的Node二進(jìn)制文件的絕對路徑。
> process.execPath
'/usr/local/bin/node'
>
execArgv屬性返回一個數(shù)組,成員是命令行下執(zhí)行腳本時,在Node可執(zhí)行文件與腳本文件之間的命令行參數(shù)。
# script.js的代碼為
# console.log(process.execArgv);
$ node --harmony script.js --version
process對象提供以下方法:
cwd方法返回進(jìn)程的當(dāng)前目錄,chdir方法用來切換目錄。
> process.cwd()
'/home/aaa'
> process.chdir('/home/bbb')
> process.cwd()
'/home/bbb'
process.nextTick()將任務(wù)放到當(dāng)前執(zhí)行棧的尾部。
process.nextTick(function () {
console.log('下一次Event Loop即將開始!');
});
上面代碼可以用setTimeout(f,0)
改寫,效果接近,但是原理不同。setTimeout(f,0)
是將任務(wù)放到當(dāng)前任務(wù)隊列的尾部,在下一次Event Loop時執(zhí)行。另外,nextTick的效率更高,因為不用檢查是否到了指定時間。
setTimeout(function () {
console.log('已經(jīng)到了下一輪Event Loop!');
}, 0)
process.exit方法用來退出當(dāng)前進(jìn)程,它可以接受一個數(shù)值參數(shù)。如果參數(shù)大于0,表示執(zhí)行失敗;如果等于0表示執(zhí)行成功。
if (err) {
process.exit(1);
} else {
process.exit(0);
}
process.exit()執(zhí)行時,會觸發(fā)exit事件。
process.on方法用來監(jiān)聽各種事件,并指定回調(diào)函數(shù)。
process.on('uncaughtException', function(err){
console.log('got an error: %s', err.message);
process.exit(1);
});
setTimeout(function(){
throw new Error('fail');
}, 100);
上面代碼是process監(jiān)聽Node的一個全局性事件uncaughtException,只要有錯誤沒有捕獲,就會觸發(fā)這個事件。
process支持的事件有以下一些。
process.on('SIGINT', function () {
console.log('Got a SIGINT. Goodbye cruel world');
process.exit(0);
});
使用時,向該進(jìn)程發(fā)出系統(tǒng)信號,就會導(dǎo)致進(jìn)程退出。
$ kill -s SIGINT [process_id]
SIGTERM信號表示內(nèi)核要求當(dāng)前進(jìn)程停止,進(jìn)程可以自行停止,也可以忽略這個信號。
var http = require('http');
var server = http.createServer(function (req, res) {
});
process.on('SIGTERM', function () {
server.close(function () {
process.exit(0);
});
});
上面代碼表示,進(jìn)程接到SIGTERM信號之后,關(guān)閉服務(wù)器,然后退出進(jìn)程。需要注意的是,這時進(jìn)程不會馬上退出,而是要回應(yīng)完最后一個請求,處理完所有回調(diào)函數(shù),然后再退出。
process.kill方法用來對指定ID的線程發(fā)送信號,默認(rèn)為SIGINT信號。
process.on('SIGTERM', function(){
console.log('terminating');
process.exit(1);
});
setTimeout(function(){
console.log('sending SIGTERM to process %d', process.pid);
process.kill(process.pid, 'SIGTERM');
}, 500);
setTimeout(function(){
console.log('never called');
}, 1000);
上面代碼中,500毫秒后向當(dāng)前進(jìn)程發(fā)送SIGTERM信號(終結(jié)進(jìn)程),因此1000毫秒后的指定事件不會被觸發(fā)。
當(dāng)前進(jìn)程退出時,會觸發(fā)exit事件,可以對該事件指定回調(diào)函數(shù)。
process.on('exit', function () {
fs.writeFileSync('/tmp/myfile', '需要保存到硬盤的信息');
});
注意,此時回調(diào)函數(shù)只能執(zhí)行同步操作,不能包含異步操作,因為執(zhí)行完回調(diào)函數(shù),進(jìn)程就會退出,無法監(jiān)聽到回調(diào)函數(shù)的操作結(jié)果。
process.on('exit', function(code) {
// 不會執(zhí)行
setTimeout(function() {
console.log('This will not run');
}, 0);
});
上面代碼在exit事件的回調(diào)函數(shù)里面,指定了一個下一輪事件循環(huán),所要執(zhí)行的操作。這是無效的,不會得到執(zhí)行。
beforeExit事件在Node清空了Event Loop以后,再沒有任何待處理的任務(wù)時觸發(fā)。正常情況下,如果沒有任何待處理的任務(wù),Node進(jìn)程會自動退出,設(shè)置beforeExit事件的監(jiān)聽函數(shù)以后,就可以提供一個機(jī)會,再部署一些任務(wù),使得Node進(jìn)程不退出。
beforeExit事件與exit事件的主要區(qū)別是,beforeExit的監(jiān)聽函數(shù)可以部署異步任務(wù),而exit不行。
此外,如果是顯式終止程序(比如調(diào)用process.exit()),或者因為發(fā)生未捕獲的錯誤,而導(dǎo)致進(jìn)程退出,這些場合不會觸發(fā)beforeExit事件。因此,不能使用該事件替代exit事件。
當(dāng)前進(jìn)程拋出一個沒有被捕捉的錯誤時,會觸發(fā)uncaughtException事件。
process.on('uncaughtException', function (err) {
console.error('An uncaught error occurred!');
console.error(err.stack);
});
部署uncaughtException事件的監(jiān)聽函數(shù),是免于node進(jìn)程終止的最后措施,否則node就要執(zhí)行process.exit()
。出于除錯的目的,并不建議發(fā)生錯誤,還保持進(jìn)程運(yùn)行。
拋出錯誤之前部署的異步操作,還是會繼續(xù)執(zhí)行。只有完成以后,Node進(jìn)程才會退出。
process.on('uncaughtException', function(err) {
console.log('Caught exception: ' + err);
});
setTimeout(function() {
console.log('本行依然執(zhí)行');
}, 500);
// 下面的表達(dá)式拋出錯誤
nonexistentFunc();
上面代碼中,拋出錯誤之后,此前setTimeout指定的回調(diào)函數(shù)亦然會執(zhí)行。
操作系統(tǒng)內(nèi)核向Node進(jìn)程發(fā)出信號,會觸發(fā)信號事件。實(shí)際開發(fā)中,主要對SIGTERM和SIGINT信號部署監(jiān)聽函數(shù),這兩個信號在非Windows平臺會導(dǎo)致進(jìn)程退出,但是只要部署了監(jiān)聽函數(shù),Node進(jìn)程收到信號后就不會退出。
// 讀取標(biāo)準(zhǔn)輸入,這主要是為了不讓當(dāng)前進(jìn)程退出
process.stdin.resume();
process.on('SIGINT', function() {
console.log('SIGINT信號,按Control-D退出');
});
上面代碼部署了SIGINT信號的監(jiān)聽函數(shù),當(dāng)用戶按下Ctrl-C后,會顯示提示文字。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: