知识共享许可协议
本作品采用知识共享署名-非商业性使用 3.0 未本地化版本许可协议进行许可。

Node.js v4.2.4 手册 & 文档


process#

process对象是一个全局对象,可以在任何地方访问到它。 它是EventEmitter的一个实例。

Exit Codes#

Node 执行程序正常情况下会返回 0,这也意味着,包括所有“异步”在内的操作都已结束。(笔者注:linux terminal 下使用 echo $? 查看,win cmd 下使用 echo %ERRORLEVEL% 查看)除此之外的其他返回状态如下:

  • 1 未捕获的致命异常(Uncaught Fatal Exception) - There was an uncaught exception, and it was not handled by a domain or an uncaughtException event handler.
  • 2 - 未使用(Unused) (reserved by Bash for builtin misuse)
  • 3 解析错误(Internal JavaScript Parse Error) - The JavaScript source code internal in Node's bootstrapping process caused a parse error. This is extremely rare, and generally can only happen during development of Node itself.
  • 4 评估失败(Internal JavaScript Evaluation Failure) - The JavaScript source code internal in Node's bootstrapping process failed to return a function value when evaluated. This is extremely rare, and generally can only happen during development of Node itself.
  • 5 致命错误(Fatal Error) - There was a fatal unrecoverable error in V8. Typically a message will be printed to stderr with the prefix FATAL ERROR.
  • 6 未正确的异常处理(Non-function Internal Exception Handler) - There was an uncaught exception, but the internal fatal exception handler function was somehow set to a non-function, and could not be called.
  • 7 异常处理函数运行时失败(Internal Exception Handler Run-Time Failure) - There was an uncaught exception, and the internal fatal exception handler function itself threw an error while attempting to handle it. This can happen, for example, if a process.on('uncaughtException') or domain.on('error') handler throws an error.
  • 8 - 未使用(Unused). In previous versions of Node, exit code 8 sometimes indicated an uncaught exception.
  • 9 - 无效的参数(Invalid Argument) - Either an unknown option was specified, or an option requiring a value was provided without a value.
  • 10 运行时失败(Internal JavaScript Run-Time Failure) - The JavaScript source code internal in Node's bootstrapping process threw an error when the bootstrapping function was called. This is extremely rare, and generally can only happen during development of Node itself.
  • 12 无效的调试参数(Invalid Debug Argument) - The --debug and/or --debug-brk options were set, but an invalid port number was chosen.
  • >128 信号退出(Signal Exits) - If Node receives a fatal signal such as SIGKILL or SIGHUP, then its exit code will be 128 plus the value of the signal code. This is a standard Unix practice, since exit codes are defined to be 7-bit integers, and signal exits set the high-order bit, and then contain the value of the signal code.

事件: 'exit'#

当进程将要退出时触发。这是一个在固定时间检查模块状态(如单元测试)的好时机。需要注意的是 'exit' 的回调结束后,主事件循环将不再运行,所以计时器也会失效。

监听 exit 事件的例子:

process.on('exit', function() {
  // 设置一个延迟执行
  setTimeout(function() {
    console.log('主事件循环已停止,所以不会执行');
  }, 0);
  console.log('退出前执行');
});

事件: 'uncaughtException'(未捕获错误)#

当一个异常冒泡回归到事件循环中就会触发这个事件,如果建立了一个监听器来监听这个异常,默认的行为(打印堆栈跟踪信息并退出)就不会发生。

监听 uncaughtException 示例:

// 故意制造一个异常,而且不catch捕获它.
nonexistentFunc();
console.log('This will not run.');

注意,uncaughtException未捕获异常是一个非常粗略的异常处理。

尽量不要使用它,使用 domains 来代替它,如果你已经使用了,请在不处理这个异常之后重启你的应用。

不要 象使用node.js的有错误回复执行这样使用.一个未处理异常意味着你的应用和你的扩展Node.js自身是有未知状态的。盲目的恢复意味着任何事情都可能发生。

你在升级的系统时拉掉了电源线,然后恢复了。可能10次里有9次每一偶问题,但是第10次,你的系统就会崩溃。

你已经被警告。

Signal Events#

当进程接收到信号时触发。信号列表详见 POSIX 标准的 sigaction(2)如 SIGINT、SIGUSR1 等。

监听 SIGINT 信号的示例:

// 设置 'SIGINT' 信号触发事件
process.on('SIGINT', function() {
  console.log('收到 SIGINT 信号。  退出请使用 Ctrl + D ');
});

在大多数终端下,一个发送 SIGINT 信号的简单方法是按下 ctrl + c

process.stdout#

一个指向标准输出流(stdout)可写的流(Writable Stream)

举例: console.log 的实现

console.log = function(d) {
  process.stdout.write(d + '\n');
}; 

process.stderr 和 process.stdout 不像 Node 中其他的流(Streams) 那样,他们通常是阻塞式的写入。当其引用指向 普通文件 或者 TTY文件描述符 时他们就是阻塞的(注:TTY 可以理解为终端的一种,可联想 PuTTY,详见百科)。当他们引用指向管道(pipes)时,他们就同其他的流(Streams)一样是非阻塞的。

要检查 Node 是否正在运行一个 TTY上下文 中(注:linux 中没有运行在 tty 下的进程是 守护进程 ),可以用使用 process.stderr、process.stdout 或 process.stdin 的 isTTY 属性:

$ node -p "Boolean(process.stdout.isTTY)"
true
$ node -p "Boolean(process.stdout.isTTY)" | cat
false 

更多信息,请查看 tty 文档

process.stderr#

一个指向标准错误流(stderr)的 可写的流(Writable Stream)。

process.stderr 和 process.stdout 不像 Node 中其他的流(Streams) 那样,他们通常是阻塞式的写入。当其引用指向 普通文件 或者 TTY文件描述符 时他们就是阻塞的(注:TTY 可以理解为终端的一种,可联想 PuTTY,详见百科)。当他们引用指向管道(pipes)时,他们就同其他的流(Streams)一样是非阻塞的。

process.stdin#

一个指向 标准输入流(stdin) 的可读流(Readable Stream)。标准输入流默认是暂停 (pause) 的,所以必须要调用 process.stdin.resume() 来恢复 (resume) 接收。

打开标准输入流,并监听两个事件的示例:

process.stdin.on('end', function() {
  process.stdout.write('end');
});


// gets 函数的简单实现
function gets(cb){
  process.stdin.resume();
  process.stdin.setEncoding('utf8');

  process.stdin.on('data', function(chunk) {
     process.stdin.pause();
     cb(chunk);
  });
}

gets(function(reuslt){
  console.log("["+reuslt+"]");
});

process.argv#

一个包含命令行参数的数组。第一个元素会是 'node', 第二个元素将是 .Js 文件的名称。接下来的元素依次是命令行传入的参数。

// 打印 process.argv
process.argv.forEach(function(val, index, array) {
  console.log(index + ': ' + val);
});

输出将会是:

$ node process-2.js one two=three four
0: node
1: /Users/mjr/work/node/process-2.js
2: one
3: two=three
4: four 

process.execPath#

开启当前进程的这个可执行文件的绝对路径。

实例:

/usr/local/bin/node 

process.execArgv#

process.argv 类似,不过是用于保存 node特殊(node-specific) 的命令行选项(参数)。这些特殊的选项不会出现在 process.argv 中,而且 process.execArgv 不会保存 process.argv 中保存的参数(如 0:node 1:文件名 2.3.4.参数 等), 所有文件名之后的参数都会被忽视。这些选项可以用于派生与与父进程相同执行环境的子进程。

实例:

$ node --harmony script.js --version 

process.execArgv 中的特殊选项:

['--harmony'] 

process.argv 接收到的参数:

['/usr/local/bin/node', 'script.js', '--version'] 

process.abort()#

这将导致 Node 触发一个abort事件,这会导致Node退出并且创建一个核心文件。

process.chdir(directory)#

改变进程的当前进程的工作目录,若操作失败则抛出异常。

console.log('当前目录:' + process.cwd());
try {
  process.chdir('/tmp');
  console.log('新目录:' + process.cwd());
}
catch (err) {
  console.log('chdir: ' + err);
}

process.cwd()#

返回进程当前的工作目录。

console.log('当前目录:' + process.cwd());

process.env#

一个包括用户环境的对象。详细参见 environ(7)。

process.exit([code])#

终止当前进程并返回给定的 code。如果省略了 code,退出是会默认返回成功的状态码('success' code) 也就是 0

退出并返回失败的状态 ('failure' code):

process.exit(1); 

执行上述代码,用来执行 node 的 shell 就能收到值为 1 的 exit code

process.exitCode#

当进程既正常退出,或者通过未指定 code 的 process.exit() 退出时,这个属性中所存储的数字将会成为进程退出的错误码 (exit code)。

如果指名了 process.exit(code) 中退出的错误码 (code),则会覆盖掉 process.exitCode 的设置。

process.getgid()#

注意: 该函数仅适用于遵循 POSIX 标准的系统平台如 Unix、Linux等 而 Windows、 Android 等则不适用。

获取进程的群组标识(详见getgid(2))。获取到的是群组的数字ID,不是群组名称。

if (process.getgid) {
  console.log('当前 gid: ' + process.getgid());
}

process.setgid(id)#

注意: 该函数仅适用于遵循 POSIX 标准的系统平台如 Unix、Linux等 而 Windows、 Android 等则不适用。

设置进程的群组标识(详见getgid(2))。参数可以是一个数字ID或者群组名字符串。如果指定了一个群组名,这个方法会阻塞等待将群组名解析为数字ID。

if (process.getgid && process.setgid) {
  console.log('当前 gid: ' + process.getgid());
  try {
    process.setgid(501);
    console.log('新 gid: ' + process.getgid());
  }
  catch (err) {
    console.log('设置 gid 失败: ' + err);
  }
}

process.getuid()#

注意: 该函数仅适用于遵循 POSIX 标准的系统平台如 Unix、Linux等 而 Windows、 Android 等则不适用。

获取执行进程的用户ID(详见getgid(2))。这是用户的数字ID,不是用户名。

if (process.getuid) {
  console.log('当前 uid: ' + process.getuid());
}

process.setuid(id)#

注意: 该函数仅适用于遵循 POSIX 标准的系统平台如 Unix、Linux等 而 Windows、 Android 等则不适用。

设置执行进程的用户ID(详见getgid(2))。参数可以使一个数字ID或者用户名字符串。如果指定了一个用户名,那么该方法会阻塞等待将用户名解析为数字ID。

if (process.getuid && process.setuid) {
  console.log('当前 uid: ' + process.getuid());
  try {
    process.setuid(501);
    console.log('新 uid: ' + process.getuid());
  }
  catch (err) {
    console.log('设置 uid 失败: ' + err);
  }
}

process.getgroups()#

注意: 该函数仅适用于遵循 POSIX 标准的系统平台如 Unix、Linux等 而 Windows、 Android 等则不适用。

返回一个保存补充组ID(supplementary group ID)的数组。POSIX 标准没有指名 如果有效组 ID(effective group ID)被包括在内的情况,而在 node.js 中则确保它始终是。(POSIX leaves it unspecified if the effective group ID is included but node.js ensures it always is. )

process.setgroups(groups)#

注意: 该函数仅适用于遵循 POSIX 标准的系统平台如 Unix、Linux等 而 Windows、 Android 等则不适用。

设置补充分组的ID标识. 这是一个特殊的操作, 意味着你必须拥有root或者CAP_SETGID权限才可以。(译者:CAP_SETGID表示设定程序允许普通用户使用setgid函数,这与文件的setgid权限位无关)

这个列表可以包括分组的ID表示,或分组名或两者都有。

process.initgroups(user, extra_group)#

注意: 该函数仅适用于遵循 POSIX 标准的系统平台如 Unix、Linux等 而 Windows、 Android 等则不适用。

读取 /etc/group 并且初始化group分组访问列表,使用改成员所在的所有分组, 这是一个特殊的操作, 意味着你必须拥有root或者CAP_SETGID权限才可以。

user 是一个用户名或者用户ID. extra_group是分组的组名或者分组ID。

有时候,当你在注销权限 (dropping privileges) 的时候需要注意。例如:

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 ]

process.version#

一个暴露编译时存储版本信息的内置变量 NODE_VERSION 的属性。

console.log('版本: ' + process.version);

process.versions#

一个暴露存储 node 以及其依赖包 版本信息的属性。

console.log(process.versions); 

输出:

{ http_parser: '1.0',
  node: '0.10.4',
  v8: '3.14.5.8',
  ares: '1.9.0-DEV',
  uv: '0.10.3',
  zlib: '1.2.3',
  modules: '11',
  openssl: '1.0.1e' }

process.config#

一个包含用来编译当前 node.exe 的配置选项的对象。内容与运行 ./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_v8: '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' } }

process.kill(pid, [signal])#

向进程发送一个信号。 pid 是进程的 id 而 signal 则是描述信号的字符串名称。信号的名称都形似 'SIGINT' 或者 'SIGUSR1'。如果没有指定参数则会默认发送 'SIGTERM' 信号,更多信息请查看 kill(2) 。

值得注意的是,这个函数的名称虽然是 process.kill, 但就像 kill 系统调用(详见《Unix高级编程》)一样,它仅仅只是一个信号发送器。而信号的发送不仅仅只是用来杀死(kill)目标进程。

向当前进程发送信号的示例:

process.kill(process.pid, 'SIGHUP'); 

process.pid#

当前进程的 PID

console.log('当前进程 id: ' + process.pid);

process.title#

获取/设置 (Getter/setter) 'ps' 中显示的进程名。

当设置该属性时,所能设置的字符串最大长度视具体平台而定,如果超过的话会自动截断。

在 Linux 和 OS X 上,它受限于名称的字节长度加上命令行参数的长度,因为它有覆盖参数内存(argv memory)。

v0.8 版本允许更长的进程标题字符串,也支持覆盖环境内存,但是存在潜在的不安全和混乱(很难说清楚)。

process.arch#

返回当前 CPU 处理器的架构:'arm'、'ia32' 或者 'x64'.

console.log('当前CPU架构是:' + process.arch);

process.platform#

返回当前程序运行的平台:'darwin', 'freebsd', 'linux', 'sunos' 或者 'win32'

console.log('当前系统平台是: ' + process.platform);

process.memoryUsage()#

返回一个对象,它描述了Node进程的内存使用情况单位是bytes。

console.log(util.inspect(process.memoryUsage())); 

输出将会是:

{ rss: 4935680,
  heapTotal: 1826816,
  heapUsed: 650472 } 

heapTotalheapUsed 是根据 V8引擎的内存使用情况来的

process.nextTick(callback)#

  • callback {Function}

在事件循环的下一次循环中调用 callback 回调函数。

不是 setTimeout(fn, 0) 函数的一个简单别名,因为它的效率高多了。该函数能在任何 I/O 事前之前调用我们的回调函数。但是这个函数在层次超过某个限制的时候,也会出现瑕疵,详细见 process.maxTickDepth

console.log('开始');
process.nextTick(function() {
  console.log('nextTick 回调');
});
console.log('已设定');
// 输出:
// 开始
// 已设定
// nextTick 回调

如果你想要在【对象创建】之后而【I/O 操作】发生之前执行某些操作,那么这个函数对你而言就十分重要了。

// thing.startDoingStuff() 现在被调用了, 而不是之前.

【注意!!】保证你的函数一定是同步执行或者一定是异步执行,这非常重要!!参考如下的例子:

  fs.stat('file', cb);
} 

这样执行是很危险。如果你还不清楚上述行为的危害请看下面的例子:

maybeSync(true, function() {
  foo();
});
bar(); 

那么,使用刚才那个不知道是同步还是异步的操作,在编程的时候你就会发现,你不能确定到底是 foo() 先执行,还是 bar() 先执行。

用下面的方法就可以更好的解决:

  fs.stat('file', cb);
} 

注意:nextTick 的队列会在完全执行完毕之后才调用 I/O 操作 (the nextTick queue is completely drained on each pass of the event loop before additional I/O is processed.) 。因此,递归设置 nextTick 的回调就像一个 while(true) ; 循环一样,将会阻止任何 I/O 操作的发生。

process.umask([mask])#

设置或者读取进程的文件模式的创建掩码。子进程从父进程中继承这个掩码。如果设定了参数 mask 那么返回旧的掩码,否则返回当前的掩码。

oldmask = process.umask(newmask);
console.log('原掩码: ' + oldmask.toString(8) + '\n'
            '新掩码: ' + newmask.toString(8));

process.uptime()#

返回 Node 程序已运行的秒数。

process.hrtime()#

返回当前的高分辨时间,形式为 [秒,纳秒] 的元组数组。它是相对于在过去的任意时间。该值与日期无关,因此不受时钟漂移的影响。主要用途是可以通过精确的时间间隔,来衡量程序的性能。

你可以将前一个 process.hrtime() 的结果传递给当前的 process.hrtime() 函数,结果会返回一个比较值,用于基准和衡量时间间隔。

  console.log('基准相差 %d 纳秒', diff[0] * 1e9 + diff[1]);
  // 基准相差 1000000527 纳秒
}, 1000);