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