process
對象是一個全局對象,并且何以被在任何地方調(diào)用。這是一個EventEmitter
實例。
當沒有任何異步操作在等待時,io.js
通常將會以一個0為退出碼退出。以下這些狀態(tài)碼會在其他情況下被用到:
domain
處理,也沒有被uncaughtException
處理。Bash
為內(nèi)建誤操作保留)。JavaScript
解析錯誤。io.js
內(nèi)部的JavaScript
源碼引導(dǎo)(bootstrapping)造成的一個解釋錯誤。這極其罕見。并且常常只會發(fā)生在io.js
自身的開發(fā)過程中。JavaScript
求值錯誤。io.js
內(nèi)部的JavaScript
源碼引導(dǎo)(bootstrapping)未能在求值時返回一個函數(shù)值。這極其罕見。并且常常只會發(fā)生在io.js
自身的開發(fā)過程中。FATAL ERROR
前綴的信息會被打印在stderr
。process.on('uncaughtException')
或domain.on('error')
處理函數(shù)拋出錯誤時發(fā)生。io.js
的之前版本中,退出碼8
通常表示一個未捕獲異常。JavaScript
運行時錯誤。io.js
內(nèi)部的JavaScript
源碼引導(dǎo)(bootstrapping)函數(shù)被調(diào)用時拋出一個錯誤。這極其罕見。并且常常只會發(fā)生在io.js
自身的開發(fā)過程中。--debug
和/或--debug-brk
選項被設(shè)置,當時選擇了一個無效的端口。io.js
收到了一個如SIGKILL
或SIGHUP
的致命信號,那么它將以一個128
加上 信號碼的值 的退出碼退出。這是一個標準的Unix實踐,因為退出碼由一個7位整數(shù)定義,并且信號的退出設(shè)置了一個高順序位(high-order bit),然后包含一個信號碼的值。進程即將退出時觸發(fā)。在這個時刻已經(jīng)沒有辦法可以阻止事件循環(huán)的退出,并且一旦所有的exit
監(jiān)聽器運行結(jié)束時,進程將會退出。因此,在這個監(jiān)聽器中你僅僅能調(diào)用同步的操作。這是檢查模塊狀態(tài)(如單元測試)的好鉤子?;卣{(diào)函數(shù)有一個退出碼參數(shù)。
例子:
process.on('exit', function(code) {
// do *NOT* do this
setTimeout(function() {
console.log('This will not run');
}, 0);
console.log('About to exit with code:', code);
});
這個事件在io.js
清空了它的事件循環(huán)并且沒有任何已安排的任務(wù)時觸發(fā)。通常io.js
當沒有更多被安排的任務(wù)時就會退出,但是beforeExit
中可以執(zhí)行異步調(diào)用,讓io.js
繼續(xù)運行。
beforeExit
在程序被顯示終止時不會觸發(fā),如process.exit()
或未捕獲的異常。除非想去安排更多的任務(wù),否則它不應(yīng)被用來做為exit
事件的替代。
當一個異常冒泡回事件循環(huán)時就會觸發(fā)。如果這個時間被添加了監(jiān)聽器,那么默認行為(退出程序且打印堆棧跟蹤信息)將不會發(fā)生。
例子:
process.on('uncaughtException', function(err) {
console.log('Caught exception: ' + err);
});
setTimeout(function() {
console.log('This will still run.');
}, 500);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');
注意,uncaughtException
來處理異常是非常粗糙的。
請不要使用它,使用domain
來替代。如果你已經(jīng)使用了它,請在不處理這個異常之后重啟你的應(yīng)用。
請不要像io.js
的Error Resume Next
這樣使用。一個未捕獲異常意味著你的應(yīng)用或拓展有未定義的狀態(tài)。盲目地恢復(fù)意味著任何事都可能發(fā)生。
想象你在升級你的系統(tǒng)時電源被拉斷了。10次中前9次都沒有問題,但是第10次時,你的系統(tǒng)崩潰了。
你已經(jīng)被警告。
在一個事件循環(huán)中,當一個promise
被“拒絕”并且沒有附屬的錯誤處理函數(shù)時觸發(fā)。當一個帶有promise
異常的程序被封裝為被“拒絕”的promise
時,這樣的程序的錯誤可以被promise.catch(...)
捕獲處理并且“拒絕”會通過promise
鏈冒泡。這個事件對于偵測和保持追蹤那些“拒絕”沒有被處理的promise
非常有用。這個事件會帶著以下參數(shù)觸發(fā):
promise
的“拒絕”對象(通常是一個錯誤實例)promise
下面是一個把所有未處理的“拒絕”打印到控制臺的例子:
process.on('unhandledRejection', function(reason, p) {
console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
// application specific logging, throwing an error, or other logic here
});
下面是一個會觸發(fā)unhandledRejection
事件的“拒絕”:
somePromise.then(function(res) {
return reportToUser(JSON.pasre(res)); // note the typo
}); // no `.catch` or `.then`
當一個Promise
被“拒絕”并且一個錯誤處理函數(shù)被附給了它(如.catch()
)時的下一個事件循環(huán)之后觸發(fā)。這個事件會帶著以下參數(shù)觸發(fā):
unhandledRejection
事件中,但現(xiàn)在被處理函數(shù)捕獲的promise
一個promise
鏈的頂端沒有 “拒絕”可以總是被處理 的概念。由于其異步的本質(zhì),一個promise
的“拒絕”可以在未來的某一個時間點被處理,可以是在事件循環(huán)中被觸發(fā)unhandledRejection
事件之后。
另外,不像同步代碼中是一個永遠增長的 未捕獲異常 列表,promise
中它是一個可伸縮的 未捕獲拒絕
列表。在同步代碼中,uncaughtException
事件告訴你 未捕獲異常 列表增長了。但是在promise
中,unhandledRejection
事件告訴你 未捕獲“拒絕” 列表增長了,rejectionHandled
事件告訴你 未捕獲“拒絕” 列表縮短了。
使用“拒絕”偵測鉤子來保持一個被“拒絕”的promise
列表:
var unhandledRejections = [];
process.on('unhandledRejection', function(reason, p) {
unhandledRejections.push(p);
});
process.on('rejectionHandled', function(p) {
var index = unhandledRejections.indexOf(p);
unhandledRejections.splice(index, 1);
});
當一個進程收到一個信號時觸發(fā)。參閱sigaction(2)
。
監(jiān)聽SIGINT
信號的例子:
// Start reading from stdin so we don't exit.
process.stdin.resume();
process.on('SIGINT', function() {
console.log('Got SIGINT. Press Control-D to exit.');
});
一個發(fā)送SIGINT
信號的快捷方法是在大多數(shù)終端中按下 Control-C 。
注意:
io.js
用于開啟調(diào)試的保留信號??梢詾槠涮砑右粋€監(jiān)聽器,但不能阻止調(diào)試的開始。io.js
將會不再退出)。signal(7)
)。它可以被添加監(jiān)聽器,但是Windows中io.js
會無條件的在10秒后關(guān)閉終端。在其他非Windows平臺,它的默認行為是結(jié)束io.js
,但是一旦被添加了監(jiān)聽器,默認行為會被移除。raw mode
時,它不會產(chǎn)生。raw mode
時發(fā)生。io.js
。注意Windows不支持發(fā)送信號,但io.js
通過process.kill()
和child_process.kill()
提供了模擬:- 發(fā)送信號0
被用來檢查進程的存在 - 發(fā)送SIGINT, SIGTERM 和 SIGKILL 會導(dǎo)致目標進程的無條件退出。
一個指向stdout
的可寫流。
例如,console.log
可能與這個相似:
console.log = function(msg) {
process.stdout.write(msg + '\n');
};
在io.js
中,process.stderr
和process.stdout
與其他流不同,因為他們不能被關(guān)閉(調(diào)用end()
會報錯)。它們永遠不觸發(fā)finish
事件并且寫操作通常是阻塞的。
當指向普通文件或TTY文件描述符時,它們是阻塞的。
以下情況下他們指向流
若要檢查io.js
是否在一個TTY上下文中運行,讀取process.stderr
,process.stdout
或process.stdin
的isTTY
屬性:
$ iojs -p "Boolean(process.stdin.isTTY)"
true
$ echo "foo" | iojs -p "Boolean(process.stdin.isTTY)"
false
$ iojs -p "Boolean(process.stdout.isTTY)"
true
$ iojs -p "Boolean(process.stdout.isTTY)" | cat
false
更多信息請參閱tty文檔。
一個指向stderr
的可寫流。
在io.js
中,process.stderr
和process.stdout
與其他流不同,因為他們不能被關(guān)閉(調(diào)用end()
會報錯)。它們永遠不觸發(fā)finish
事件并且寫操作通常是阻塞的。
當指向普通文件或TTY文件描述符時,它們是阻塞的。
以下情況下他們指向流
一個指向stdin
的可讀流。
一個打開標準輸入并且監(jiān)聽兩個事件的例子:
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');
});
作為一個流,process.stdin
可以被切換至“舊”模式,這樣就可以兼容node.js
v0.10 前所寫的腳本。更多信息請參閱 流的兼容性 。
在“舊”模式中stdin
流默認是被暫停的。所以你必須調(diào)用process.stdin.resume()
來讀取。注意調(diào)用process.stdin.resume()
這個操作本身也會將流切換至舊模式。
如果你正將開啟一個新的工程。你應(yīng)該要更常使用“新”模式的流。
一個包含了命令行參數(shù)的數(shù)組。第一次元素將會是'iojs'
,第二個元素將會是JavaScript
文件名。之后的元素將會是額外的命令行參數(shù)。
// print process.argv
process.argv.forEach(function(val, index, array) {
console.log(index + ': ' + val);
});
這將會是:
$ iojs process-2.js one two=three four
0: iojs
1: /Users/mjr/work/iojs/process-2.js
2: one
3: two=three
4: four
這將是開啟進程的可執(zhí)行文件的絕對路徑名:
例子:
/usr/local/bin/iojs
這是在啟動時io.js
自身參數(shù)的集合。這些參數(shù)不會出現(xiàn)在process.argv
中,并且不會包含io.js
可執(zhí)行文件,腳本名和其他腳本名之后的參數(shù)。這些參數(shù)對開啟和父進程相同執(zhí)行環(huán)境的子進程非常有用。
例子:
$ iojs --harmony script.js --version
process.execArgv
將會是:
['--harmony']
process.argv
將會是:
['/usr/local/bin/iojs', 'script.js', '--version']
這將導(dǎo)致io.js
觸發(fā)abort
事件。這個將導(dǎo)致io.js
退出,并創(chuàng)建一個核心文件。
為進程改變當前工作目錄,如果失敗,則拋出一個異常。
console.log('Starting directory: ' + process.cwd());
try {
process.chdir('/tmp');
console.log('New directory: ' + process.cwd());
}
catch (err) {
console.log('chdir: ' + err);
}
返回進程的當前工作目錄。
console.log('Current directory: ' + process.cwd());
包含用戶環(huán)境變量的對象。參閱environ(7)
。
一個例子:
{ TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/iojs' }
你可以改寫這個對象,但是改變不會反應(yīng)在你的進程之外。這以為著以下代碼不會正常工作:
$ iojs -e 'process.env.foo = "bar"' && echo $foo
但是以下代碼會:
process.env.foo = 'bar';
console.log(process.env.foo);
使用指定的退出碼退出程序,如果忽略退出碼。那么將使用“成功”退出碼0
。
以一個“失敗”退出碼結(jié)束:
process.exit(1);
在執(zhí)行io.js
的shell中可以看到為1
的退出碼。
將是程序退出碼的數(shù)字,當程序優(yōu)雅退出 或 被process.exit()
關(guān)閉且沒有指定退出碼時。
為process.exit(code)
指定一個退出碼會覆蓋之前的process.exitCode
設(shè)置。
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
獲取進程的群組標識(參閱getgid(2)
)。這是一個群組id數(shù)組,不是群組名。
if (process.getgid) {
console.log('Current gid: ' + process.getgid());
}
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
獲取進程的有效群組標識(參閱getgid(2)
)。這是一個群組id數(shù)組,不是群組名。
if (process.getegid) {
console.log('Current gid: ' + process.getegid());
}
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
設(shè)置進程的群組標識(參閱setgid(2)
)。它接受一個數(shù)字ID或一個群組名字符串。如果群組名被指定,那么這個方法將在解析群組名為一個ID的過程中阻塞。
if (process.getgid && process.setgid) {
console.log('Current gid: ' + process.getgid());
try {
process.setgid(501);
console.log('New gid: ' + process.getgid());
}
catch (err) {
console.log('Failed to set gid: ' + err);
}
}
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
設(shè)置進程的有效群組標識(參閱setgid(2)
)。它接受一個數(shù)字ID或一個群組名字符串。如果群組名被指定,那么這個方法將在解析群組名為一個ID的過程中阻塞。
if (process.getegid && process.setegid) {
console.log('Current gid: ' + process.getegid());
try {
process.setegid(501);
console.log('New gid: ' + process.getegid());
}
catch (err) {
console.log('Failed to set gid: ' + err);
}
}
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
獲取進程的用戶id(參閱getuid(2)
)。這是一個數(shù)字用戶id,不是用戶名。
if (process.getuid) {
console.log('Current uid: ' + process.getuid());
}
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
獲取進程的有效用戶id(參閱getuid(2)
)。這是一個數(shù)字用戶id,不是用戶名。
if (process.geteuid) {
console.log('Current uid: ' + process.geteuid());
}
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
設(shè)置進程的用戶ID(參閱setuid(2)
)。它接受一個數(shù)字ID或一個用戶名字符串。如果用戶名被指定,那么這個方法將在解析用戶名為一個ID的過程中阻塞。
if (process.getuid && process.setuid) {
console.log('Current uid: ' + process.getuid());
try {
process.setuid(501);
console.log('New uid: ' + process.getuid());
}
catch (err) {
console.log('Failed to set uid: ' + err);
}
}
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
設(shè)置進程的有效用戶ID(參閱seteuid(2)
)。它接受一個數(shù)字ID或一個用戶名字符串。如果用戶名被指定,那么這個方法將在解析用戶名為一個ID的過程中阻塞。
if (process.geteuid && process.seteuid) {
console.log('Current uid: ' + process.geteuid());
try {
process.seteuid(501);
console.log('New uid: ' + process.geteuid());
}
catch (err) {
console.log('Failed to set uid: ' + err);
}
}
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
返回一個補充群組ID的數(shù)組。如果包含了有效的組ID,POSIX將不會指定。但io.js
保證它始終是。
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
設(shè)置一個補充群組ID。這是一個特殊的操作,意味著你需要擁有root
或CAP_SETGID
權(quán)限才可以這么做。
列表可以包含群組ID,群組名,或兩者。
注意:這個函數(shù)只在POSIX平臺上有效(如在Windows,Android中無效)。
讀取/etc/group
并且初始化群組訪問列表,使用用戶是組員的所有群組。這是一個特殊的操作,意味著你需要擁有root
或CAP_SETGID
權(quán)限才可以這么做。
user
是一個用戶名或一個用戶ID。extra_group
是一個群組名或群組ID。
當你注銷權(quán)限時有些需要關(guān)心的:
console.log(process.getgroups()); // [ 0 ]
process.initgroups('bnoordhuis', 1000); // switch user
console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ]
process.setgid(1000); // drop root gid
console.log(process.getgroups()); // [ 27, 30, 46, 1000 ]
一個暴露NODE_VERSION
的編譯時存儲屬性。
console.log('Version: ' + process.version);
一個暴露io.js版本和它的依賴的字符串屬性。
console.log(process.versions);
將可能打?。?/p>
{ http_parser: '2.3.0',
node: '1.1.1',
v8: '4.1.0.14',
uv: '1.3.0',
zlib: '1.2.8',
ares: '1.10.0-DEV',
modules: '43',
openssl: '1.0.1k' }
一個表示用于編譯當前io.js
執(zhí)行文件的配置的JavaScript對象。這和運行./configure
腳本產(chǎn)生的config.gypi
一樣。
一個可能的輸出:
{ target_defaults:
{ cflags: [],
default_configuration: 'Release',
defines: [],
include_dirs: [],
libraries: [] },
variables:
{ host_arch: 'x64',
node_install_npm: 'true',
node_prefix: '',
node_shared_cares: 'false',
node_shared_http_parser: 'false',
node_shared_libuv: 'false',
node_shared_zlib: 'false',
node_use_dtrace: 'false',
node_use_openssl: 'true',
node_shared_openssl: 'false',
strict_aliasing: 'true',
target_arch: 'x64',
v8_use_snapshot: 'true' } }
給進程傳遞一個信號。pid
是進程id,signal
是描述信號的字符串。信號碼類似于'SIGINT'
或'SIGHUP'
。如果忽略,那么信號將是'SIGTERM'
。更多信息參閱Signal Events
和kill(2)
。
如果目標不存在將會拋出一個錯誤,并且在一些情況下,0
信號可以被用來測試進程的存在。
注意,這個函數(shù)僅僅是名字為process.kill
,它只是一個信號發(fā)送者。發(fā)送的信號可能與殺死進程無關(guān)。
一個發(fā)送信號給自身的例子:
process.on('SIGHUP', function() {
console.log('Got SIGHUP signal.');
});
setTimeout(function() {
console.log('Exiting.');
process.exit(0);
}, 100);
process.kill(process.pid, 'SIGHUP');
注意:當SIGUSR1
被io.js
收到,它會開始調(diào)試。參閱Signal Events
。
process.pid#
進程的PID。
console.log('This process is pid ' + process.pid);
process.title#
設(shè)置/獲取 'ps'
中顯示的進程名。
當設(shè)置該屬性時,所能設(shè)置的字符串最大長度視具體平臺而定,如果超過的話會自動截斷。
在 Linux 和 OS X 上,它受限于名稱的字節(jié)長度加上命令行參數(shù)的長度,因為它有覆蓋參數(shù)內(nèi)存。
v0.8 版本允許更長的進程標題字符串,也支持覆蓋環(huán)境內(nèi)存,但是存在潛在的不安全和混亂。
返回當前的處理器結(jié)構(gòu):'arm'
,'ia32'
或'x64'
。
console.log('This processor architecture is ' + process.arch);
放回當前的平臺:'darwin'
,'freebsd'
,'linux'
,'sunos'
或'win32'
。
console.log('This platform is ' + process.platform);
返回當前io.js
進程內(nèi)存使用情況(用字節(jié)描述)的對象。
var util = require('util');
console.log(util.inspect(process.memoryUsage()));
可能的輸出:
{ rss: 4935680,
heapTotal: 1826816,
heapUsed: 650472 }
heapTotal
和heapUsed
指向V8的內(nèi)存使用。
在事件循環(huán)的下一次循環(huán)中調(diào)用回調(diào)函數(shù)。
這不是setTimeout(fn, 0)
的簡單別名,它更有效率。在之后的tick
中,它在任何其他的I/O事件(包括timer
)觸發(fā)之前運行。
console.log('start');
process.nextTick(function() {
console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback
這對于開發(fā)你想要給予用戶在對象被構(gòu)建后,任何I/O發(fā)生前,去設(shè)置事件監(jiān)聽器的機會時,非常有用。
function MyThing(options) {
this.setupOptions(options);
process.nextTick(function() {
this.startDoingStuff();
}.bind(this));
}
var thing = new MyThing();
thing.getReadyForStuff();
// thing.startDoingStuff() gets called now, not before.
這對于100%同步或100%異步的API非常重要。考慮一下例子:
// WARNING! DO NOT USE! BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
if (arg) {
cb();
return;
}
fs.stat('file', cb);
}
這個API是危險的,如果你這樣做:
maybeSync(true, function() {
foo();
});
bar();
foo()
和bar()
的調(diào)用次序是不確定的。
更好的做法是:
function definitelyAsync(arg, cb) {
if (arg) {
process.nextTick(cb);
return;
}
fs.stat('file', cb);
}
注意:nextTick
隊列在每一次事件循環(huán)的I/O開始前都要完全執(zhí)行完畢。所以,遞歸地設(shè)置nextTick
回調(diào)會阻塞I/O的方法,就像一個while(true);
循環(huán)。
設(shè)置或讀取進程的文件模式的創(chuàng)建掩碼。子進程從父進程中繼承這個掩碼。返回舊的掩碼如果mask
參數(shù)被指定。否則,會返回當前掩碼。
var oldmask, newmask = 0022;
oldmask = process.umask(newmask);
console.log('Changed umask from: ' + oldmask.toString(8) +
' to ' + newmask.toString(8));
io.js
進程已執(zhí)行的秒數(shù)。
以[seconds, nanoseconds]
元組數(shù)組的形式返回高分辨時間。是相對于過去的任意時間。它與日期無關(guān)所以不用考慮時區(qū)等因素。它的主要用途是衡量程序性能。
你可以將之前的process.hrtime()
返回傳遞給一個新的process.hrtime()
來獲得一個比較。衡量性能時非常有用:
var time = process.hrtime();
// [ 1800216, 25 ]
setTimeout(function() {
var diff = process.hrtime(time);
// [ 1, 552 ]
console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);
// benchmark took 1000000527 nanoseconds
}, 1000);
檢索require.main
的備用方式。區(qū)別是,如果主模塊在運行時改變,require.main
可能仍指向改變發(fā)生前的被引入的原主模塊。通常,假設(shè)它們一樣是安全的。
與require.main
一樣,當如果沒有入口腳本時,它將是undefined
。
更多建議: