process對象是一個全局對象,并且何以被在任何地方調用。這是一個EventEmitter實例。
當沒有任何異步操作在等待時,io.js通常將會以一個0為退出碼退出。以下這些狀態(tài)碼會在其他情況下被用到:
domain處理,也沒有被uncaughtException處理。Bash為內建誤操作保留)。JavaScript解析錯誤。io.js內部的JavaScript源碼引導(bootstrapping)造成的一個解釋錯誤。這極其罕見。并且常常只會發(fā)生在io.js自身的開發(fā)過程中。JavaScript求值錯誤。io.js內部的JavaScript源碼引導(bootstrapping)未能在求值時返回一個函數(shù)值。這極其罕見。并且常常只會發(fā)生在io.js自身的開發(fā)過程中。FATAL ERROR前綴的信息會被打印在stderr。process.on('uncaughtException')或domain.on('error')處理函數(shù)拋出錯誤時發(fā)生。io.js的之前版本中,退出碼8通常表示一個未捕獲異常。JavaScript運行時錯誤。io.js內部的JavaScript源碼引導(bootstrapping)函數(shù)被調用時拋出一個錯誤。這極其罕見。并且常常只會發(fā)生在io.js自身的開發(fā)過程中。--debug和/或--debug-brk選項被設置,當時選擇了一個無效的端口。io.js收到了一個如SIGKILL或SIGHUP的致命信號,那么它將以一個128加上 信號碼的值 的退出碼退出。這是一個標準的 Unix 實踐,因為退出碼由一個7位整數(shù)定義,并且信號的退出設置了一個高順序位(high-order bit),然后包含一個信號碼的值。進程即將退出時觸發(fā)。在這個時刻已經沒有辦法可以阻止事件循環(huán)的退出,并且一旦所有的exit監(jiān)聽器運行結束時,進程將會退出。因此,在這個監(jiān)聽器中你僅僅能調用同步的操作。這是檢查模塊狀態(tài)(如單元測試)的好鉤子?;卣{函數(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)并且沒有任何已安排的任務時觸發(fā)。通常io.js當沒有更多被安排的任務時就會退出,但是beforeExit中可以執(zhí)行異步調用,讓io.js繼續(xù)運行。
beforeExit在程序被顯示終止時不會觸發(fā),如process.exit()或未捕獲的異常。除非想去安排更多的任務,否則它不應被用來做為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來替代。如果你已經使用了它,請在不處理這個異常之后重啟你的應用。
請不要像io.js的Error Resume Next這樣使用。一個未捕獲異常意味著你的應用或拓展有未定義的狀態(tài)。盲目地恢復意味著任何事都可能發(fā)生。
想象你在升級你的系統(tǒng)時電源被拉斷了。10次中前9次都沒有問題,但是第10次時,你的系統(tǒ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鏈的頂端沒有 “拒絕”可以總是被處理 的概念。由于其異步的本質,一個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用于開啟調試的保留信號??梢詾槠涮砑右粋€監(jiān)聽器,但不能阻止調試的開始。io.js將會不再退出)。signal(7))。它可以被添加監(jiān)聽器,但是 Windows 中io.js會無條件的在10秒后關閉終端。在其他非Windows 平臺,它的默認行為是結束io.js,但是一旦被添加了監(jiān)聽器,默認行為會被移除。raw mode時,它不會產生。raw mode時發(fā)生。io.js。注意 Windows 不支持發(fā)送信號,但io.js通過process.kill()和child_process.kill()提供了模擬:- 發(fā)送信號0被用來檢查進程的存在 - 發(fā)送 SIGINT, SIGTERM 和 SIGKILL 會導致目標進程的無條件退出。
一個指向stdout的可寫流。
例如,console.log可能與這個相似:
console.log = function(msg) {
process.stdout.write(msg + '\n');
};
在io.js中,process.stderr和process.stdout與其他流不同,因為他們不能被關閉(調用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與其他流不同,因為他們不能被關閉(調用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流默認是被暫停的。所以你必須調用process.stdin.resume()來讀取。注意調用process.stdin.resume()這個操作本身也會將流切換至舊模式。
如果你正將開啟一個新的工程。你應該要更常使用“新”模式的流。
一個包含了命令行參數(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']
這將導致io.js觸發(fā)abort事件。這個將導致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' }
你可以改寫這個對象,但是改變不會反應在你的進程之外。這以為著以下代碼不會正常工作:
$ iojs -e 'process.env.foo = "bar"' && echo $foo
但是以下代碼會:
process.env.foo = 'bar';
console.log(process.env.foo);
使用指定的退出碼退出程序,如果忽略退出碼。那么將使用“成功”退出碼0。
以一個“失敗”退出碼結束:
process.exit(1);
在執(zhí)行io.js的 shell 中可以看到為1的退出碼。
將是程序退出碼的數(shù)字,當程序優(yōu)雅退出 或 被process.exit()關閉且沒有指定退出碼時。
為process.exit(code)指定一個退出碼會覆蓋之前的process.exitCode設置。
注意:這個函數(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 中無效)。
設置進程的群組標識(參閱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 中無效)。
設置進程的有效群組標識(參閱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 中無效)。
設置進程的用戶 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 中無效)。
設置進程的有效用戶 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 中無效)。
設置一個補充群組 ID。這是一個特殊的操作,意味著你需要擁有root或CAP_SETGID權限才可以這么做。
列表可以包含群組 ID,群組名,或兩者。
注意:這個函數(shù)只在 POSIX 平臺上有效(如在 Windows,Android 中無效)。
讀取/etc/group并且初始化群組訪問列表,使用用戶是組員的所有群組。這是一個特殊的操作,意味著你需要擁有root或CAP_SETGID權限才可以這么做。
user是一個用戶名或一個用戶 ID。extra_group是一個群組名或群組 ID。
當你注銷權限時有些需要關心的:
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腳本產生的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ā)送的信號可能與殺死進程無關。
一個發(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收到,它會開始調試。參閱Signal Events。
進程的 PID。
console.log('This process is pid ' + process.pid);
設置/獲取 'ps' 中顯示的進程名。
當設置該屬性時,所能設置的字符串最大長度視具體平臺而定,如果超過的話會自動截斷。
在 Linux 和 OS X 上,它受限于名稱的字節(jié)長度加上命令行參數(shù)的長度,因為它有覆蓋參數(shù)內存。
v0.8 版本允許更長的進程標題字符串,也支持覆蓋環(huán)境內存,但是存在潛在的不安全和混亂。
返回當前的處理器結構:'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進程內存使用情況(用字節(jié)描述)的對象。
var util = require('util');
console.log(util.inspect(process.memoryUsage()));
可能的輸出:
{ rss: 4935680,
heapTotal: 1826816,
heapUsed: 650472 }
heapTotal和heapUsed指向V8的內存使用。
在事件循環(huán)的下一次循環(huán)中調用回調函數(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ā)你想要給予用戶在對象被構建后,任何 I/O 發(fā)生前,去設置事件監(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()的調用次序是不確定的。
更好的做法是:
function definitelyAsync(arg, cb) {
if (arg) {
process.nextTick(cb);
return;
}
fs.stat('file', cb);
}
注意:nextTick隊列在每一次事件循環(huán)的 I/O 開始前都要完全執(zhí)行完畢。所以,遞歸地設置nextTick回調會阻塞 I/O 的方法,就像一個while(true);循環(huán)。
設置或讀取進程的文件模式的創(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ù)組的形式返回高分辨時間。是相對于過去的任意時間。它與日期無關所以不用考慮時區(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ā)生前的被引入的原主模塊。通常,假設它們一樣是安全的。
與require.main一樣,當如果沒有入口腳本時,它將是undefined。