Node.js v8.x 中文文档
目录
- process - 进程
- process 事件
- process.abort()
- process.arch
- process.argv
- process.argv0
- process.channel
- process.chdir(directory)
- process.config
- process.connected
- process.cpuUsage([previousValue])
- process.cwd()
- process.disconnect()
- process.emitWarning(warning[, options])
- process.emitWarning(warning[, type[, code]][, ctor])
- process.env
- process.execArgv
- process.execPath
- process.exit([code])
- process.exitCode
- process.getegid()
- process.geteuid()
- process.getgid()
- process.getgroups()
- process.getuid()
- process.hrtime([time])
- process.initgroups(user, extra_group)
- process.kill(pid[, signal])
- process.mainModule
- process.memoryUsage()
- process.nextTick(callback[, ...args])
- process.noDeprecation
- process.pid
- process.platform
- process.ppid
- process.release
- process.send(message[, sendHandle[, options]][, callback])
- process.setegid(id)
- process.seteuid(id)
- process.setgid(id)
- process.setgroups(groups)
- process.setuid(id)
- process.stderr
- process.stdin
- process.stdout
- process.throwDeprecation
- process.title
- process.traceDeprecation
- process.umask([mask])
- process.uptime()
- process.version
- process.versions
- Exit Codes
process - 进程#
process
对象是一个全局变量,它提供当前 Node.js 进程的有关信息,以及控制当前 Node.js 进程。
因为是全局变量,所以无需使用 require()
。
process 事件#
process
对象是 EventEmitter
的实例。
'beforeExit' 事件#
当 Node.js 的事件循环数组已经为空,并且没有额外的工作被添加进来,事件 'beforeExit'
会被触发。
正常情况下,如果没有额外的工作被添加到事件循环数组,Node.js 进程会结束。
但是如果 'beforeExit'
事件绑定的监听器的回调函数中,含有一个可以进行异步调用的操作,那么 Node.js 进程会继续运行。
process.exitCode
作为唯一的参数值传递给 'beforeExit'
事件监听器的回调函数。
如果进程由于显式的原因而将要终止,例如直接调用 process.exit()
或抛出未捕获的异常,'beforeExit'
事件不会被触发。
除非本意就是需要添加额外的工作(比如通过监听器进行异步调用)到事件循环数组,否则不应该用 'beforeExit'
事件替代 'exit'
事件。
'disconnect' 事件#
如果 Node.js 进程是由 IPC 通道的方式创建的(详见子进程和集群文档),当 IPC 通道关闭时,会触发'disconnect'
事件。
'exit' 事件#
两种情况下 'exit'
事件会被触发:
- 显式调用
process.exit()
方法,使得 Node.js 进程即将结束; - Node.js 事件循环数组中不再有额外的工作,使得 Node.js 进程即将结束。
在上述两种情况下,没有任何方法可以阻止事件循环的结束,一旦所有与 'exit'
事件绑定的监听器执行完成,Node.js 的进程会终止。
'exit'
事件监听器的回调函数,只有一个入参,这个参数的值可以是 process.exitCode
的属性值,或者是调用 process.exit()
方法时传入的 exitCode
值。
例如:
process.on('exit', (code) => {
console.log(`即将退出,退出码:${code}`);
});
'exit'
事件监听器的回调函数,只允许包含同步操作。所有监听器的回调函数被调用后,任何在事件循环数组中排队的工作都会被强制丢弃,然后 Nodje.js 进程会立即结束。
例如在下例中,定时器中的操作永远不会被执行(因为不是同步操作)。
process.on('exit', (code) => {
setTimeout(() => {
console.log('该函数不会被执行');
}, 0);
});
'message' 事件#
如果 Node.js 进程是由 IPC 通道的方式创建的(详见子进程和集群文档),当子进程收到父进程发送的消息时(消息通过 childprocess.send()
发送),会触发 'message'
事件。
通过下列参数触发回调:
message
<Object> 解析的 JSON 对象或原始值。sendHandle
<Handle object> 一个net.Socket
或net.Server
对象,或undefined
。
注意: 这个消息经过序列化和解析,可能与原初发送的消息不完全一样。
'rejectionHandled' 事件#
如果有 Promise
被 rejected,并且此 Promise
在 Node.js 事件循环的下次轮询及之后期间,被绑定了一个错误处理器(例如使用 promise.catch()
),会触发 'rejectionHandled'
事件。
此事件监听器的回调函数使用 rejected 的 Promise
引用,作为唯一入参。
Promise
对象应该已经在 'unhandledRejection'
事件触发时被处理,但是在被处理过程中获得了一个 rejection 处理器。
对于 Promise
链,没有概念表明在 Promise
链的哪个地方,所有的 rejection 总是会被处理。
由于本来就是异步的,一个 Promise
rejection 可以在将来的某个时间点被处理-可能要远远晚于 'unhandledRejection'
事件被触发及处理的时间。
另一种表述的方式就是,与使用同步代码时会出现不断增长的未处理异常列表不同,使用 Promise
时,未处理异常列表可能会出现增长然后收缩的情况。
在同步代码情况下,当未处理异常列表增长时,会触发 'uncaughtException'
事件。
在异步代码情况下,当未处理异常列表增长时,会触发 'uncaughtException'
事件,当未处理列表收缩时,会触发 'rejectionHandled'
事件。
例如:
const unhandledRejections = new Map();
process.on('unhandledRejection', (reason, p) => {
unhandledRejections.set(p, reason);
});
process.on('rejectionHandled', (p) => {
unhandledRejections.delete(p);
});
在上述例子中,unhandledRejections
会随着时间增加和缩减,表明 rejection 开始是未被处理状态,然后变成已处理状态。
可以定时(对于需长期运行的应用,这个可能是最好的方式)或当进程结束时(对脚本的应用可能是最方便的),在错误日志中记录这些错误信息。
'uncaughtException' 事件#
如果 Javascript 未捕获的异常,沿着代码调用路径反向传递回事件循环,会触发 'uncaughtException'
事件。
Node.js 默认情况下会将这些异常堆栈打印到 stderr
然后进程退出。
为 'uncaughtException'
事件增加监听器会覆盖上述默认行为。
'uncaughtException'
事件监听器的回调函数,使用 Error
对象作为唯一参数值。
例如:
process.on('uncaughtException', (err) => {
fs.writeSync(1, `捕获到异常:${err}\n`);
});
setTimeout(() => {
console.log('这里仍然会运行。');
}, 500);
// 故意调用一个不存在的函数,应用会抛出未捕获的异常。
nonexistentFunc();
console.log('这里不会运行。');
注意:正确地使用 uncaughtException
#
需要注意,如果打算使用 'uncaughtException'
事件作为异常处理的最后补救机制,这是非常粗糙的设计方式。
此事件不应该当作 On Error Resume Next
(出了错误就恢复让它继续)的等价机制。
未处理异常本身就意味着应用已经处于了未定义的状态。如果基于这种状态,尝试恢复应用正常进行,可能会造成未知或不可预测的问题。
此事件的监听器回调函数中抛出的异常,不会被捕获。为了避免出现无限循环的情况,进程会以非零的状态码结束,并打印堆栈信息。
如果在出现未捕获异常时,尝试去恢复应用,可能出现的结果与电脑升级时拔掉电源线出现的结果类似 -- 10次中有9次不会出现问题,但是第10次可能系统会出现错误。
正确使用 'uncaughtException'
事件的方式,是用它在进程结束前执行一些已分配资源(比如文件描述符,句柄等等)的同步清理操作。
触发 'uncaughtException'
事件后,用它来尝试恢复应用正常运行的操作是不安全的。
想让一个已经崩溃的应用正常运行,更可靠的方式应该是启动另外一个进程来监测/探测应用是否出错,
无论 uncaughtException
事件是否被触发,如果监测到应用出错,则恢复或重启应用。
'unhandledRejection' 事件#
如果在事件循环的一次轮询中,一个 Promise
被 rejected,并且此 Promise
没有绑定错误处理器,'unhandledRejection
事件会被触发。
当使用 Promise 进行编程时,异常会以 "rejected promises" 的形式封装。Rejection 可以被 promise.catch()
捕获并处理,并且在 Promise
链中传播。'unhandledRejection
事件在探测和跟踪 promise 被 rejected,并且 rejection 未被处理的场景中是很有用的。
此事件监听器的回调函数被传递如下参数:
例如:
process.on('unhandledRejection', (reason, p) => {
console.log('未处理的 rejection:', p, '原因:', reason);
// 记录日志、抛出错误、或其他逻辑。
});
somePromise.then((res) => {
return reportToUser(JSON.pasre(res)); // 故意输错 `pasre`。
}); // 没有 `.catch` 或 `.then`。
如下代码也会触发'unhandledRejection'
事件
function SomeResource() {
// 将 loaded 的状态设置为一个 rejected promise。
this.loaded = Promise.reject(new Error('错误信息'));
}
const resource = new SomeResource();
// resource.loaded 上没有 .catch 或 .then。
在例子中,可以像在其他 'unhandledRejection'
事件的典型场景中一样,跟踪开发者错误导致的 rejection。
为了解决这样的错误,resource.loaded
中可以加一个不做任何操作的 .catch(() => { })
处理器,
这样可以阻止 'unhandledRejection'
事件的触发。或者也可以使用 'rejectionHandled'
事件来解决。
'warning' 事件#
任何时候Node.js发出进程告警,都会触发'warning'
事件。
进程告警与进程错误的相似之处,在于两者都描述了需要引起用户注意的异常条件。 区别在于,告警不是Node.js和Javascript错误处理流程的正式组成部分。 一旦探测到可能导致应用性能问题,缺陷或安全隐患相关的代码实践,Node.js就可发出告警。
'warning'
事件监听器的回调函数,参数只有一个,其值为Error
对象。此对象有三个重要的属性用来描述告警:
name
<string> 告警的名称(目前默认值是Warning
)。message
<string> 系统提供的对此告警的描述。stack
<string> 当告警触发时,包含代码位置的堆栈信息。
process.on('warning', (warning) => {
console.warn(warning.name); // 打印告警名称
console.warn(warning.message); // 打印告警信息
console.warn(warning.stack); // 打印堆栈信息
});
默认Node.js会打印进程告警到stderr
。使用--no-warnings
的命令行选项可以阻止默认从console输出信息,
但是'warning'
事件仍然会被process
对象发出。
下面的例子展示了当一个事件绑定了太多的监听器时,输出到stderr
的告警。
$ node
> events.defaultMaxListeners = 1;
> process.on('foo', () => {});
> process.on('foo', () => {});
> (node:38638) MaxListenersExceededWarning: Possible EventEmitter memory leak
detected. 2 foo listeners added. Use emitter.setMaxListeners() to increase limit
与上述相反,如下例子关闭了默认的告警输出,并且给'warning'
事件添加了一个定制的处理器。
$ node --no-warnings
> const p = process.on('warning', (warning) => console.warn('Do not do that!'));
> events.defaultMaxListeners = 1;
> process.on('foo', () => {});
> process.on('foo', () => {});
> Do not do that!
--trace-warnings
命令行选项可以让默认的console输出告警信息时,包含告警的全部堆栈信息。
使用--throw-deprecation
命令行选项标志启动Node.js,会使得custom deprecation warning作为异常信息抛出来。
使用--trace-deprecation
命令行选项标志,会使得custom deprecation warning打印到stderr
,包括其堆栈信息。
使用--no-deprecation
命令行选项标志,会阻止报告所有的custom deprecation warning。
*-deprecation
命令行选项标志,只会影响使用名字为DeprecationWarning
的告警。
触发自定义的告警#
查看process.emitWarning()
的描述,其中包含关于触发定制告警或特定应用告警的信息。
信号事件#
当Node.js进程接收到一个信号时,会触发信号事件。 signal(7)列出了标准POSIX的信号名称列表,例如SIGINT
, SIGHUP
等等。
每个事件名称,以信号名称的大写表示 (比如事件'SIGINT'
对应信号 SIGINT
).
例如:
// Begin reading from stdin so the process does not exit.
process.stdin.resume();
process.on('SIGINT', () => {
console.log('Received SIGINT. Press Control-D to exit.');
});
SIGUSR1
被Node.js保留用于启动调试器。可以为此事件绑定一个监听器,但是即使这样做也不会阻止调试器的启动。SIGTERM
和SIGINT
在非windows平台绑定了默认的监听器,这样进程以代码128 + signal number
结束之前,可以重置终端模式。 如果这两个事件任意一个绑定了新的监听器,原有默认的行为会被移除(Node.js不会结束)。SIGPIPE
默认会被忽略。可以给其绑定监听器。SIGHUP
在Windows平台中当console窗口被关闭时会触发它,在非windows平台中多种相似的条件下也会触发,查看signal(7)。 可以给其绑定监听器,但是Windows下Node.js会在它触发后10秒钟无条件关闭。 非windows平台,SIGHUP
默认的绑定行为是结束Node.js,但是一旦给它绑定了新的监听器,默认行为会被移除。SIGTERM
在Windows中不支持,可以给其绑定监听器。SIGINT
在终端运行时,可以被所有平台支持,通常可以通过<Ctrl>+C
触发(虽然这个不能配置)。 当终端运行在raw模式,它不会被触发。SIGBREAK
在Windows中按下<Ctrl>+<Break>
会被触发,非Windows平台中可以为其绑定监听器,但是没有方式触发或发送此事件。SIGWINCH
当console被resize时会触发。Windows中只有当光标移动并写入到console,或者以raw模式使用一个可读tty时,才会触发。SIGKILL
不能绑定监听器,所有平台中出现此事件,都会使得Node.js无条件终止。SIGSTOP
不能绑定监听器。SIGBUS
,SIGFPE
,SIGSEGV
andSIGILL
, 如果不是通过kill(2)产生,默认会使进程停留在某个状态,在此状态下尝试调用JS监听器是不安全的。 如果尝试调用JS监听器可能会导致进程在无限循环中挂死,因为使用process.on()
附加的监听器是以异步的方式被调用,因此不能纠正隐含的问题。
Note: Windows不支持发送信号,但是Node.js通过process.kill()
, 和 subprocess.kill()
提供了某些模拟机制。
发送信号0
可以测试进程是否存在。发送SIGINT
, SIGTERM
, and SIGKILL
使得目标进程无条件终止。
process.abort()#
process.abort()
方法会使Node.js进程立即结束,并生成一个core文件。
process.arch#
process.arch
属性返回一个表示操作系统CPU架构的字符串,Node.js二进制文件是为这些架构编译的。
例如
'arm'
, 'arm64'
, 'ia32'
, 'mips'
, 'mipsel'
, 'ppc'
, 'ppc64'
, 's390'
, 's390x'
, 'x32'
, 或 'x64'
。
console.log(`This processor architecture is ${process.arch}`);
process.argv#
process.argv
属性返回一个数组,这个数组包含了启动Node.js进程时的命令行参数。第一个元素为process.execPath
。如果需要获取argv[0]
的值请参见 process.argv0
。第二个元素为当前执行的JavaScript文件路径。剩余的元素为其他命令行参数。
例如,process-args.js
文件有以下代码:
// print process.argv
process.argv.forEach((val, index) => {
console.log(`${index}: ${val}`);
});
运行以下命令,启动进程:
$ node process-args.js one two=three four
将输出:
0: /usr/local/bin/node
1: /Users/mjr/work/node/process-args.js
2: one
3: two=three
4: four
process.argv0#
process.argv0
属性,保存Node.js启动时传入的argv[0]
参数值的一份只读副本。
$ bash -c 'exec -a customArgv0 ./node'
> process.argv[0]
'/Volumes/code/external/node/out/Release/node'
> process.argv0
'customArgv0'
process.channel#
如果Node.js进程是由IPC channel(请看 Child Process 文档) 方式创建的,process.channel
属性保存IPC channel的引用。
如果IPC channel不存在,此属性值为undefined
。
process.chdir(directory)#
directory
<string>
process.chdir()
方法变更Node.js进程的当前工作目录,如果变更目录失败会抛出异常(例如,如果指定的目录不存在)。
console.log(`Starting directory: ${process.cwd()}`);
try {
process.chdir('/tmp');
console.log(`New directory: ${process.cwd()}`);
} catch (err) {
console.error(`chdir: ${err}`);
}
process.config#
process.config
属性返回一个Javascript对象。此对象描述了用于编译当前Node.js执行程序时涉及的配置项信息。
这与执行./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'
}
}
注意: process.config
属性值不是只读的,在Node.js生态系统中已经有模块扩展,修改或完全替换了process.config
的值。
process.connected#
如果Node.js进程是由IPC channel方式创建的(请看[Child Process子进程][] 和 [Cluster集群][] 文档),
只要IPC channel保持连接,process.connected
属性就会返回true
。
process.disconnect()
被调用后,此属性会返回false
。
process.connected
如果为false
,则不能通过IPC channel使用process.send()
发送信息。
process.cpuUsage([previousValue])#
process.cpuUsage()
方法返回包含当前进程的用户CPU时间和系统CPU时间的对象。此对象包含user
和system
属性,属性值的单位都是微秒(百万分之一秒)。
user
和system
属性值分别计算了执行用户程序和系统程序的时间,如果此进程在执行任务时是基于多核CPU,值可能比实际花费的时间要大。
上一次调用process.cpuUsage()
方法的结果,可以作为参数值传递给此方法,得到的结果是与上一次的差值。
const startUsage = process.cpuUsage();
// { user: 38579, system: 6986 }
// spin the CPU for 500 milliseconds
const now = Date.now();
while (Date.now() - now < 500);
console.log(process.cpuUsage(startUsage));
// { user: 514883, system: 11226 }
process.cwd()#
- 返回: <string>
process cwd()
方法返回 Node.js 进程当前工作的目录。
console.log('Current directory: ${process.cwd()}');
process.disconnect()#
如果 Node.js 进程是从IPC频道派生出来的(具体看 Child Process 和 Cluster 的文档), process.disconnect()
函数会关闭到父进程的IPC频道,以允许子进程一旦没有其他链接来保持活跃就优雅地关闭。
调用process.disconnect()
的效果和父进程调用ChildProcess.disconnect()
的一样ChildProcess.disconnect()
.
如果 Node.js 进程不是从IPC频道派生出来的,那调用process.disconnect()
函数的结果是undefined
.
process.emitWarning(warning[, options])#
warning
<string> | <Error> 发出的警告。options
<Object>type
<string> 如果warning
是String,type
是警告类型的名字。 默认值:Warning
。code
<string> 当前警告的唯一标识符。ctor
<Function> 如果warning
是String,ctor
是可选的function,用于限制生成的堆栈信息。默认process.emitWarning
detail
<string> error的附加信息。
process.emitWarning()
方法可用于发出定制的或应用特定的进程警告。
可以通过给process.on('warning')
事件增加处理器,监听这些警告。
// Emit a warning with a code and additional detail.
process.emitWarning('Something happened!', {
code: 'MY_WARNING',
detail: 'This is some additional information'
});
// Emits:
// (node:56338) [MY_WARNING] Warning: Something happened!
// This is some additional information
在上面例子中,process.emitWarning()
内部生成了一个Error
对象,并传递给process.on('warning')
事件。
process.on('warning', (warning) => {
console.warn(warning.name); // 'Warning'
console.warn(warning.message); // 'Something happened!'
console.warn(warning.code); // 'MY_WARNING'
console.warn(warning.stack); // Stack trace
console.warn(warning.detail); // 'This is some additional information'
});
如果warning
参数值是一个Error
对象,options
参数项都会被忽略。
process.emitWarning(warning[, type[, code]][, ctor])#
warning
<string> | <Error> 发出的警告。type
<string> 如果warning
是String,type
是警告类型的名字。 默认值:Warning
。code
<string> 当前警告的唯一标识符。ctor
<Function> 如果warning
是String,ctor
是可选的function,用于限制生成的堆栈信息。默认process.emitWarning
process.emitWarning()
方法可用于发出定制的或应用特定的进程警告。
可以通过给process.on('warning')
事件增加处理器,监听这些警告。
// Emit a warning using a string.
process.emitWarning('Something happened!');
// Emits: (node: 56338) Warning: Something happened!
// Emit a warning using a string and a type.
process.emitWarning('Something Happened!', 'CustomWarning');
// Emits: (node:56338) CustomWarning: Something Happened!
process.emitWarning('Something happened!', 'CustomWarning', 'WARN001');
// Emits: (node:56338) [WARN001] CustomWarning: Something happened!
在上面例子中,process.emitWarning()
内部生成了一个Error
对象,并传递给process.on('warning')
事件。
process.on('warning', (warning) => {
console.warn(warning.name);
console.warn(warning.message);
console.warn(warning.code);
console.warn(warning.stack);
});
如果warning
参数值是一个Error
对象,它会被透传给process.on('warning')
的事件监听器(可选参数值type
,code
and ctor
会被忽略):
// Emit a warning using an Error object.
const myWarning = new Error('Something happened!');
// Use the Error name property to specify the type name
myWarning.name = 'CustomWarning';
myWarning.code = 'WARN001';
process.emitWarning(myWarning);
// Emits: (node:56338) [WARN001] CustomWarning: Something happened!
如果warning
的参数值不是string或Error
,会抛出 TypeError
。
需要注意的是,使用Error
对象做为进程警告,并不是常用的错误处理机制的替代方式。
如果警告type
是DeprecationWarning
,会涉及如下额外的处理:
如果命令行标识包含
--throw-deprecation
,deprecation warning会作为异常抛出,而不是作为事件被发出。如果命令行标识包含
--no-deprecation
,deprecation warning会被忽略。如果命令行标识包含
--trace-deprecation
,deprecation warning及其全部堆栈信息会被打印到stderr
。
Avoiding duplicate warnings#
作为最佳实践,警告应该在每个进程中最多发出一次。
为了达到上述的要求,推荐在使用emitWarning()
之前用一个简单的布尔值做判断,如下例所示:
function emitMyWarning() {
if (!emitMyWarning.warned) {
emitMyWarning.warned = true;
process.emitWarning('Only warn once!');
}
}
emitMyWarning();
// Emits: (node: 56339) Warning: Only warn once!
emitMyWarning();
// Emits nothing
process.env#
process.env
属性返回一个包含用户环境信息的对象
See 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/node'
}
可以修改这个对象,但是下面例子的做法是不会生效的:
$ node -e 'process.env.foo = "bar"' && echo $foo
下面的做法会生效:
process.env.foo = 'bar';
console.log(process.env.foo);
在process.env
中新增一个属性,会将属性值转换成字符串
例如:
process.env.test = null;
console.log(process.env.test);
// => 'null'
process.env.test = undefined;
console.log(process.env.test);
// => 'undefined'
用 delete
从process.env
中删除一个属性
例如:
process.env.TEST = 1;
delete process.env.TEST;
console.log(process.env.TEST);
// => undefined
在Windows系统下,环境变量是不区分大小写的
例如:
process.env.TEST = 1;
console.log(process.env.test);
// => 1
process.execArgv#
process.execArgv
属性返回当Node.js进程被启动时,Node.js特定的命令行选项。
这些选项在process.argv
属性返回的数组中不会出现,并且这些选项中不会包括Node.js的可执行脚本名称或者任何在脚本名称后面出现的选项。
这些选项在创建子进程时是有用的,因为他们包含了与父进程一样的执行环境信息。
例如:
$ node --harmony script.js --version
process.execArgv
的结果:
['--harmony']
process.argv
的结果:
['/usr/local/bin/node', 'script.js', '--version']
process.execPath#
process.execPath
属性,返回启动Node.js进程的可执行文件所在的绝对路径。
例如:
'/usr/local/bin/node'
process.exit([code])#
code
<integer> 结束状态码。默认为0
。
process.exit()
方法以结束状态码code
指示Node.js同步终止进程。
如果code
未提供,此exit方法要么使用'success' 状态码 0
,要么使用process.exitCode
属性值,前提是此属性已被设置。
Node.js在所有'exit'
事件监听器都被调用了以后,才会终止进程。
使用一个'failure'状态码结束的例子:
process.exit(1);
执行Node.js的shell应该会得到结束状态码1
。
调用 process.exit()
会强制进程尽快结束,即使仍然有很多处于等待中的异步操作没有全部执行完成,
包括输出到 process.stdout
和 process.stderr
的 I/O 操作。
在大多数情况下,显式调用process.exit()
是没有必要的。如果在事件轮询队列中没有处于等待中的工作,Node.js进程会自行结束。
当进程正常结束时,process.exitCode
属性可以被设置,以便于告知进程使用哪个结束状态码。
如下例子说明了一个 错误使用 process.exit()
方法的场景,会导致输出到stdout的数据清空或丢失:
// This is an example of what *not* to do:
if (someConditionNotMet()) {
printUsageToStdout();
process.exit(1);
}
这个例子中出现问题的原因在于,Node.js中写入到process.stdout
的操作有时是异步的,并可能在Node.js事件轮询的多个ticks中出现。
调用process.exit()
会使得在写入stdout
的额外操作执行之前,进程就被强制结束了。
与直接调用process.exit()
相比,代码应该设置process.exitCode
并允许进程自然的结束,以免事件轮询队列中存在额外的工作:
// How to properly set the exit code while letting
// the process exit gracefully.
if (someConditionNotMet()) {
printUsageToStdout();
process.exitCode = 1;
}
如果出现错误情况,而有必要结束Node.js进程,抛出一个uncaught错误并且允许进程正常结束的处理方式,要比调用process.exit()
安全的多。
process.exitCode#
当进程正常结束,或通过process.exit()
结束但未传递参数时,此数值标识进程结束的状态码。
给process.exit(code)
指定一个状态码,会覆盖process.exitCode
的原有值。
process.getegid()#
process.getegid()
方法返回Node.js进程的有效数字标记的组身份(See getegid(2))。
if (process.getegid) {
console.log(`Current gid: ${process.getegid()}`);
}
注意:这个函数只在POSIX平台有效(在Windows或Android平台无效)。
process.geteuid()#
- Returns: <Object>
process.geteuid()
方法返回Node.js进程的有效数字标记的用户身份(See geteuid(2))。
if (process.geteuid) {
console.log(`Current uid: ${process.geteuid()}`);
}
注意:这个函数只在POSIX平台有效(在Windows或Android平台无效)。
process.getgid()#
- Returns: <Object>
process.getgid()
方法返回Node.js进程的数字标记的组身份(See getgid(2))。
if (process.getgid) {
console.log(`Current gid: ${process.getgid()}`);
}
注意:这个函数只在POSIX平台有效(在Windows或Android平台无效)。
process.getgroups()#
- Returns: <Array>
process.getgroups()
方法返回数组,其中包含了补充的组ID。
如果包含有效的组ID,POSIX会将其保留为未指定状态,但 Node.js 会确保它始终处于状态。
注意:这个函数只在POSIX平台有效(在Windows或Android平台无效)。
process.getuid()#
- Returns: <integer>
process.getuid()
方法返回Node.js进程的数字标记的用户身份(See getuid(2))。
if (process.getuid) {
console.log(`Current uid: ${process.getuid()}`);
}
注意:这个函数只在POSIX平台有效(在Windows或Android平台无效)。
process.hrtime([time])#
process.hrtime()
方法返回当前时间以[seconds, nanoseconds]
tuple Array表示的高精度解析值,
nanoseconds
是当前时间无法使用秒的精度表示的剩余部分。
time
是可选参数,传入的值是上一次调用process.hrtime()
返回的结果,用于与当次调用做差值计算。
如果此参数传入的不是一个tuple Array,会抛出TypeError
。
给此参数传入一个用户定义的数组,而不是传入上次调用process.hrtime()
的结果,会导致未定义的行为。
process.hrtime()
返回的时间,都是相对于过去某一时刻的值,与一天中的时钟时间没有关系,因此不受制于时钟偏差。
此方法最主要的作用是衡量间隔操作的性能:
const NS_PER_SEC = 1e9;
const time = process.hrtime();
// [ 1800216, 25 ]
setTimeout(() => {
const diff = process.hrtime(time);
// [ 1, 552 ]
console.log(`Benchmark took ${diff[0] * NS_PER_SEC + diff[1]} nanoseconds`);
// benchmark took 1000000552 nanoseconds
}, 1000);
process.initgroups(user, extra_group)#
process.initgroups()
方法读取/etc/group
文件,并且初始化组访问列表,该列表包括了用户所在的所有组。
该方法需要Node.js进程有root
访问或者有CAP_SETGID
capability才能操作。
替换gid并舍弃权限时需要格外谨慎。例如:
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 ]
注意:这个函数只在POSIX平台有效(在Windows或Android平台无效)。
process.kill(pid[, signal])#
process.kill()
方法将signal
发送给pid
标识的进程。
信号名称是如'SIGINT'
或 'SIGHUP'
的字符串。更多信息,查看Signal Events 和 kill(2)。
如果目标pid
不存在,该方法会抛出错误。作为一个特殊例子,信号0
可以用于测试进程是否存在。
在Windows平台中,如果pid
用于kill进程组,会抛出错误。
注意:即使这个函数的名称是process.kill()
,它其实只是发送信号,这点与kill
系统调用类似。
发送的信号可能是做一些与kill目标进程无关的事情。
例如:
process.on('SIGHUP', () => {
console.log('Got SIGHUP signal.');
});
setTimeout(() => {
console.log('Exiting.');
process.exit(0);
}, 100);
process.kill(process.pid, 'SIGHUP');
注意: 当Node.js进程接收到了SIGUSR1
,Node.js会启动debugger,查看Signal Events。
process.mainModule#
process.mainModule
属性提供了一种获取require.main
的替代方式。
区别在于,若主模块在运行时中发生改变,
require.main
可能仍然指向变化之前所依赖的模块
一般来说,假定require.main
和process.mainModule
引用相同的模块是安全的。
就像require.main
一样,如果没有入口脚本,process.mainModule
的值是undefined
。
process.memoryUsage()#
process.memoryUsage()
方法返回Node.js进程的内存使用情况的对象,该对象每个属性值的单位为字节。
例如:
console.log(process.memoryUsage());
会得到:
{
rss: 4935680,
heapTotal: 1826816,
heapUsed: 650472,
external: 49879
}
heapTotal
和 heapUsed
代表V8的内存使用情况。
external
代表V8管理的,绑定到Javascript的C++对象的内存使用情况。
rss
, 驻留集大小, 是给这个进程分配了多少物理内存(占总分配内存的一部分)
这些物理内存中包含堆,栈,和代码段。
对象,字符串,闭包等存于堆内存。 变量存于栈内存。 实际的JavaScript源代码存于代码段内存。
process.nextTick(callback[, ...args])#
callback
<Function>...args
<any> 调用callback
时传递给它的额外参数
process.nextTick()
方法将 callback
添加到"next tick 队列"。
一旦当前事件轮询队列的任务全部完成,在next tick队列中的所有callbacks会被依次调用。
这种方式不是setTimeout(fn, 0)
的别名。它更加有效率。事件轮询随后的ticks 调用,会在任何I/O事件(包括定时器)之前运行。
console.log('start');
process.nextTick(() => {
console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback
此方法在开发如下API时非常重要:在对象构造好但还没有任何I/O发生之前,想给用户机会来指定某些事件处理器。
function MyThing(options) {
this.setupOptions(options);
process.nextTick(() => {
this.startDoingStuff();
});
}
const 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是危险的:
const maybeTrue = Math.random() > 0.5;
maybeSync(maybeTrue, () => {
foo();
});
bar();
因为不清楚foo()
或 bar()
哪个会被先调用。
如下方式要更好一些:
function definitelyAsync(arg, cb) {
if (arg) {
process.nextTick(cb);
return;
}
fs.stat('file', cb);
}
注意: 每次事件轮询后,在额外的I/O执行前,next tick队列都会优先执行。
递归调用nextTick callbacks 会阻塞任何I/O操作,就像一个while(true);
循环一样。
process.noDeprecation#
The process.noDeprecation
property indicates whether the --no-deprecation
flag is set on the current Node.js process. See the documentation for
the warning
event and the
emitWarning
method for more information about this
flag's behavior.
process.pid#
process.pid
属性返回进程的PID。
console.log(`This process is pid ${process.pid}`);
process.platform#
process.platform
属性返回字符串,标识Node.js进程运行其上的操作系统平台。
例如
'aix'
'darwin'
'freebsd'
'linux'
'openbsd'
'sunos'
'win32'
console.log(`This platform is ${process.platform}`);
The value 'android'
may also be returned if the Node.js is built on the
Android operating system. However, Android support in Node.js
is experimental.
process.ppid#
process.ppid
属性返回当前父进程的进程ID
console.log(`The parent process is pid ${process.ppid}`);
process.release#
process.release
属性返回与当前发布相关的元数据对象,包括源代码和源代码头文件 tarball的URLs。
process.release
包括如下属性:
name
<string> 对于Node.js, 此值始终为'node'
。对于传统io.js 发布包, 此值为'io.js'
。sourceUrl
<string> 指向一个.tar.gz
文件的绝对URL,包括了当前发布的源代码。headersUrl
<string> 指向一个.tar.gz
文件的绝对URL,包括了当前发布的源代码的头文件信息。 这个文件要比全部源代码文件明显小很多,可以用于编译Node.js原生插件。libUrl
<string> 指向一个node.lib
文件的绝对URL,匹配当前发布的结构和版本信息。此文件用于编译Node.js本地插件。 _这个属性只在Windows版本中存在,在其他平台中无效。lts
<string> 标识当前发布的LTS标签的字符串。 只有长效版(Long Term Support/LTS)存在这个属性,其他所有版本类型这个属性都是undefined
, 包括Current版本,当前的有效值有:'Argon'
for the 4.x LTS line beginning with 4.2.0.'Boron'
for the 6.x LTS line beginning with 6.9.0.'Carbon'
for the 8.x LTS line beginning with 8.9.1.
例如:
{
name: 'node',
lts: 'Argon',
sourceUrl: 'https://nodejs.org/download/release/v4.4.5/node-v4.4.5.tar.gz',
headersUrl: 'https://nodejs.org/download/release/v4.4.5/node-v4.4.5-headers.tar.gz',
libUrl: 'https://nodejs.org/download/release/v4.4.5/win-x64/node.lib'
}
从源码树的非发布版本中构建的定制版本,可能只有name
属性有效。其他的属性不一定会存在。
process.send(message[, sendHandle[, options]][, callback])#
message
<Object>sendHandle
<Handle object>options
<Object>callback
<Function>- Returns: <boolean>
如果Node.js进程是通过进程间通信产生的,那么,process.send()方法可以用来给父进程发送消息。
接收到的消息被视为父进程的ChildProcess
对象上的一个'message'
事件。
如果Node.js进程不是通过进程间通信产生的, process.send()
会是undefined
。
注意: 消息传递时,以格式序列化和解析,结果消息与发送时未必完全一样。
process.setegid(id)#
process.setegid()
方法为进程设置有效的用户组ID。(请看 setegid(2).)
id
可以传一个数值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}`);
}
}
注意: 这个方法只在POSIX平台可用(换句话说,Windows或Android不行)。
process.seteuid(id)#
process.seteuid()
方法为进程设置有效的用户ID。(请看 seteuid(2).)
id
可以传一个数值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}`);
}
}
注意: 这个方法只在POSIX平台可用(换句话说,Windows或Android不行)。
process.setgid(id)#
process.setgid()
为进程方法设置组ID. (查看setgid(2).)
可给id
参数传一个数值ID或字符串名。
如果已经有一个进程组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}`);
}
}
注意: 这个方法只在POSIX平台可用(换句话说,Windows或Android不行)。
process.setgroups(groups)#
groups
<Array>
The process.setgroups()
method sets the supplementary group IDs for the
Node.js process. This is a privileged operation that requires the Node.js process
to have root
or the CAP_SETGID
capability.
The groups
array can contain numeric group IDs, group names or both.
Note: This function is only available on POSIX platforms (i.e. not Windows or Android).
process.setuid(id)#
process.setuid(id)
设置进程的用户ID (参见
setuid(2).) id
可以是一个数值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}`);
}
}
注意: 这个方法只在POSIX平台可用(换句话说,Windows或Android不行)。
process.stderr#
process.stderr
属性返回连接到stderr
(fd 2
)的流。
它是一个net.Socket
(它是一个Duplex流),除非 fd 2
指向一个文件,在这种情况下它是一个[可写][]流。
注意: process.stderr
与其他 Node.js 流有重要的区别,详见 note on process I/O。
process.stdin#
process.stdin
属性返回连接到 stdin
(fd 0
)的流。
它是一个net.Socket
(它是一个Duplex流),除非 fd 0
指向一个文件,在这种情况下它是一个Readable流。
举个例子:
process.stdin.setEncoding('utf8');
process.stdin.on('readable', () => {
const chunk = process.stdin.read();
if (chunk !== null) {
process.stdout.write(`data: ${chunk}`);
}
});
process.stdin.on('end', () => {
process.stdout.write('end');
});
process.stdin
返回的 Duplex 流, 可以在旧
模式下使用,兼容node v0.10。
更多信息查看流的兼容性。
注意: 在"旧模式下" stdin
流 默认是暂停的.所以必须通过执行.stdin.resume()
来恢复它.
同时process.stdin.resume()
会切换到旧模式
process.stdout#
process.stdout
属性返回连接到 stdout
(fd 1
)的流。
它是一个net.Socket
(它是一个Duplex流), 除非 fd 1
指向一个文件,在这种情况下它是一个[可写][]流。
例1: 将输入流数据输出到输出流,即输出到终端。
process.stdin.pipe(process.stdout);
例2: 要求用户输入两个数值,然后把和输出到终端。
/*1:声明变量*/
var num1, num2;
/*2:向屏幕输出,提示信息,要求输入num1*/
process.stdout.write('请输入num1的值:');
/*3:监听用户的输入*/
process.stdin.on('data', function (chunk) {
if (!num1) {
num1 = Number(chunk);
/*4:向屏幕输出,提示信息,要求输入num2*/
process.stdout.write('请输入num2的值');
} else {
num2 = Number(chunk);
process.stdout.write('结果是:' + (num1 + num2));
}
});
注意: 重要的是process.stdout
不同于 Node.js 的其他流,
详情可以参考note on process I/O .
A note on process I/O#
process.stdout
and process.stderr
与 Node.js 中其他 streams 在重要的方面有不同:
- 他们分别使用内部的
console.log()
和console.error()
。 - 他们不能被关闭 (调用
end()
将会抛出异常)。 - 他们永远不会触发
'finish'
事件。 写操作是否为同步,取决于连接的是什么流以及操作系统是 Windows 还是 POSIX :
- Files: 同步 在 Windows 和 POSIX 下
- TTYs (Terminals): 异步 在 Windows 下, 同步 在 POSIX 下
- Pipes (and sockets): 同步 在 Windows 下, 异步 在 POSIX 下
这些行为部分是历史原因,改变他们可能导致向后不兼容,而且他们的行为也符合部分用户的预期。
同步写避免了调用 console.log()
或 console.error()
产生不符合预期的交错输出问题,或是在异步写完成前调用了process.exit()
导致未写完整。 查看process.exit()
获取更多信息。
警告: 同步写将会阻塞事件循环直到写完成。 有时可能一瞬间就能写到一个文件,但当系统处于高负载时,管道的接收端可能不会被读取、缓慢的终端或文件系统,因为事件循环被阻塞的足够频繁且足够长的时间,这些可能会给系统性能带来消极的影响。当你向一个交互终端会话写时这可能不是个问题,但当生产日志到进程的输出流时要特别留心。
如果要检查一个流是否连接到了一个 TTY 上下文, 检查 isTTY
属性。
例如:
$ node -p "Boolean(process.stdin.isTTY)"
true
$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"
false
$ node -p "Boolean(process.stdout.isTTY)"
true
$ node -p "Boolean(process.stdout.isTTY)" | cat
false
查看 TTY 文档以获得更多信息。
process.throwDeprecation#
process.throwDeprecation
属性表示--throw-deprecation
标记是否被设置到当前Node.js进程上。
请查看 warning
event 和emitWarning
method 的文档,
来获取这个标记行为的更多信息。
process.title#
process.title
属性用于获取或设置当前进程在 ps
命令中显示的进程名字
注意:当分配新值时,不同的平台会对标题施加不同的最大长度限制。 通常这种限制是相当有限的。 例如,在 Linux 和 macOS 上,process.title
仅限于二进制名称的大小加上命令行参数的长度,因为设置 process.title
会覆盖进程的argv内存。Node.js 的 v0.8, 通过覆盖 environ
允许内存较长的过程标题字符串,但是这在一些(相当模糊的)可能是不安全的并且令人困惑情况下。
process.traceDeprecation#
The process.traceDeprecation
property indicates whether the
--trace-deprecation
flag is set on the current Node.js process. See the
documentation for the warning
event and the
emitWarning
method for more information about this
flag's behavior.
process.umask([mask])#
mask
<number>
process.umask()
方法用于返回或设置Node.js进程的默认创建文件的权限掩码。子进程从父进程继承这个掩码。
不传参数时,默认返回当前掩码,如果传递了参数,创建文件掩码就被设置为参数值,并且返回之前的掩码。
const newmask = 0o022;
const oldmask = process.umask(newmask);
console.log(
`Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}`
);
process.uptime()#
- Returns: <number>
process.uptime()
方法返回当前 Node.js 进程运行时间秒长
注意: 该返回值包含秒的分数。 使用 Math.floor()
来得到整秒钟。
process.version#
process.version
属性返回Node.js的版本信息。
console.log(`Version: ${process.version}`);
process.versions#
process.versions
属性返回一个对象,此对象列出了Node.js和其依赖的版本信息。
process.versions.modules
表明了当前ABI版本,此版本会随着一个C++API变化而增加。
Node.js会拒绝加载模块,如果这些模块使用一个不同ABI版本的模块进行编译。
console.log(process.versions);
会显示类似下面的对象信息:
{ http_parser: '2.7.0',
node: '8.9.0',
v8: '6.3.292.48-node.6',
uv: '1.18.0',
zlib: '1.2.11',
ares: '1.13.0',
modules: '60',
nghttp2: '1.29.0',
napi: '2',
openssl: '1.0.2n',
icu: '60.1',
unicode: '10.0',
cldr: '32.0',
tz: '2016b' }
Exit Codes#
正常情况下,如果没有异步操作正在等待,那么Node.js会以状态码0
退出,其他情况下,会
用如下的状态码:
1
未捕获异常 - 有一个未被捕获的异常, 并且没被一个 domain 或 an'uncaughtException'
事件处理器处理。2
- 未被使用 (Bash为防内部滥用而保留)3
内部JavaScript 分析错误 - Node.js的内部的JavaScript源代码 在引导进程中导致了一个语法分析错误。 这是非常少见的, 一般只会在开发Node.js本身的时候出现。4
内部JavaScript执行失败 - 引导进程执行Node.js的内部的JavaScript源代码时,返回函数值失败。 这是非常少见的, 一般只会在开发Node.js本身的时候出现。5
致命错误 - 在V8中有一个致命的错误. 比较典型的是以FATALERROR
为前缀从stderr打印出来的消息。6
非函数的内部异常处理 - 发生了一个内部异常,但是内部异常处理函数 被设置成了一个非函数,或者不能被调用。7
内部异常处理运行时失败 - 有一个不能被捕获的异常。 在试图处理这个异常时,处理函数本身抛出了一个错误。 这是可能发生的, 比如, 如果一个'uncaughtException'
或者domain.on('error')
处理函数抛出了一个错误。8
- 未被使用. 在之前版本的Node.js, 退出码8有时候表示一个未被捕获的异常。9
- 不可用参数 - 也许是某个未知选项没有确定,或者没给必需要的选项填值。10
内部JavaScript运行时失败 - 调用引导函数时, 引导进程执行Node.js的内部的JavaScript源代码抛出错误。 这是非常少见的, 一般只会在开发Node.js本身的时候出现。12
不可用的调试参数 ---inspect
和/或--inspect-brk
选项已设置,但选择的端口号无效或不可用。>128
退出信号 - 如果Node.js的接收信号致命诸如SIGKILL
或SIGHUP
,那么它的退出代码将是128
加上信号的码值。 这是POSIX的标准做法,因为退出码被定义为7位整数,并且信号退出设置高位,然后包含信号码值。
- 断言测试
- 异步钩子(Async Hooks)
- 缓存(Buffer)
- C++ 插件
- C/C++ 插件 - N-API
- 子进程
- 集群(Cluster)
- 命令行参数
- 控制台(Console)
- 加密(Crypto)
- 调试器
- 废弃的 API
- DNS
- 域(Domain)
- ECMAScript 模块
- 错误(Errors)
- 事件(Events)
- 文件系统
- 全局对象(Globals)
- HTTP
- HTTP/2
- HTTPS
- 检查工具(Inspector)
- 国际化
- 模块(Modules)
- 网络(Net)
- 操作系统(OS)
- 路径(Path)
- 性能钩子(Performance Hooks)
- 进程
- Punycode
- 查询字符串
- 逐行读取
- 交互式解释器(REPL)
- 流(Stream)
- 字符串解码
- 定时器(Timers)
- 安全传输层(TLS/SSL)
- 事件跟踪(Tracing)
- TTY
- UDP / 数据报
- URL
- 工具集
- V8
- 虚拟机(VM)
- 压缩(ZLIB)