process
process是nodejs用来控制和管理进程的工具。
beforeExit
当node清空其事件循环,没有额外的工作要安排时会触发beforeExit事件。也就是说当nodejs没有事情要做,或者其他的事情都做完了之后会触发beforeExit事件。
const process=require('process');
process.on('beforeExit',code=>{
console.log('触发了beforeExit事件',code);
})
console.log(123);
//当nodejs打印完123之后,此时没有事情要做了,会触发beforeExit事件
// 如果node没有事情做是因为process.exit()进行的终止不会触发beforeExit事件
exit
exit事件,也是在node清空其事件循环没有额外的工作要安排时会触发exit事件,而且在调用process.exit()时也会触发exit事件,在exit事件和beforeExit事件共存时,会先触发exit事件再触发beforeExit是事件
const process=require('process');
process.on('exit',code=>{
console.log('触发exit事件',code);
});
process.on('beforeExit',code=>{
console.log('触发了beforeExit事件',code);
})
process.exit(); //process.exit以后的代码不会执行
//调用process.exit();不会触发beforeExit事件
//如果不调用process.exit(); 会先打印123然后再触发exit事件,再触发beforeExit事件
console.log(123);
disconnect
当主进程断开与子进程的连接时会触发disconnect事件
// index.js 主进程
const process=require('process');
const child_process=require('child_process');
const child=child_process.fork('./child.js');
child.send('Hello,My son');
child.disconnect(); //调用disconnect事件断开与子进程的连接】
// child.js 子进程
process.on('disconnect',()=>{
console.log('即将断开连接')
})
message
当子进程接收到父进程传递过来的消息时会触发message事件
//父进程传递消息
const process=reuqire('process');
const child_process=reuqire('child_process');
const child=child_process.fork('./child.js'); //连接到子进程
child.send('Hello,My Son')
//子进程接收消息 work.js
process.onI('message',e=>{
//e就是传递过来的数据
console.log(e,'Father Message');
})
异常处理事件
rejectionHandled && unhandledRejection (用于捕获异步的异常)
rejectionHandled和unhandledRejection都是用于处理promise错误未处理的事件的,例如:我们一般使用promise可能只写then但是不写catch就会触发unhandledRejection事件,写了catch且不在一轮事件循环中会触发rejectionHandled事件
const unHandledMaps=new Map(); //新建一个map用于存储未处理的proimise
process.on('unhandledRejection',(reason,promise)=>{
console.log('触发到了unhandled事件');
unHandledMaps.set(reason,promise);
})
process.on('rejectionHandled',promise=>{
console.log('触发了rejectionHandled事件');
})
const rejected=Promise.reject('Error'); //promise有了错误,但是未用catch处理,会触发unhandledRejection事件
//为了不在一轮事件循环写一个定时器
setTimeout(()=>{
rejected.catch(()=>{}); //用间隔0.1秒用catch处理了,此时会触发rejectionHandled事件
},100);
uncaughtException && uncaughtExceptionMonitor (捕获同步的异常)
uncaughtEcxcertion用于捕获异常,捕获到异常后进行异常处理,uncaughtExceptionMonitor会率先一步uncaughtException捕获到异常,但是如果没有注册uncaughtException事件,只注册uncaughtExceptionMonitor事件的话进程会直接报错。
process.on('uncaughtException',(err,origin)=>{
console.log('捕获到了异常',err);
})
process.on('uncaughtExceptionMonitor',(err,origin)=>{
console.log('率先捕获到了异常');
})
function foo(){
throw new Error();
}
foo();
// 此时执行foo的话如果不注册uncaughtException事件,进程会直接报错
// 但是注册了uncaughtException事件的话会执行异常处理后,再退出进程
//如果只注册了uncaughtExceptionMonitor会直接报错,不存在异常处理情况
信号事件
无论我们的node部署在哪里,比如当我们的进程停止时,运行node的系统会发出信号,触发信号事件,信号事件是在liunx系统独有的,在windows不会发出信号
abort()
abort方法会立即退出进程,并且生成一个核心文件,但是在worke里此方法不可用
process.abort();
allowedNodeEnvironmentFlags
返回node_options环境变量允许的标志
const process=require('process');
console.log(process.allowedNodeEnvironmentFlags);
arch argv
arch返回当前正在运行node的系统的cpu架构 ,window是x64 argv 返回一个数组,里边包含node的路径,当前正在执行js的路径,接下来的内容是运行进程时传入的参数
//我们可以这样运行我们的进程
// node index.js 11 然后看下面的打印内容
const process=reuqire('process');
console.log(process.arch); // x64
console.log(process.argv); // ['node的路径','当前执行js的路径','11']
channel
channel属性只在子进程里有效,如果当前进程不是子进程则channel的值为undefined,
ref unref()
ref方法保持进程的事件循环运行,unref()终止进程的事件循环
// 子进程child.js
process.on('message',(e)=>{
console.log(e);
})
process.ref(); // 保持事件循环运行,正常触发message事件然后打印
process.unref();// 终止事件循环运行,message事件不会被触发
config
process的全局属性,可以修改
console.log(process.config)
connected
判断主进程与子进程是否连接 连接:true 未连接:flase
// index.js 主进程
const process=require('process');
const child_process=require('child_process');
const child=child_process.fork('./child.js');
console.log(child.connected); // true
child.disconnect();
console.log(child.connected); //false
// child.js 子进程
console.log(process.connected); //true
cpuUsage
返回当前的进程的user和cpu运行的时间,单位是百万分之一秒, 接收一个参数
const process=require('process')
const user=process.cpuUsage(); //可以保存数据,作为下一次cpuUsage的参数查看差异
setTimeout(()=>{console.log(process.cpuUsage(user))},500);
cwd
cwd方法返回当前进程的工作目录
console.log(process.cwd());
disconnect
断开与父进程的连接
// index.js 父进程
const process=reuqire('process');
const child_process=reuqire('child_process');
const child=child_process.fork('./child.js');
child.disconnect();
// child.js 子进程
process.on('disconnect',()=>{
console.log('连接即将关闭');
})
// 在父进程调用child.disconnect() 的作用与 在子进程 process.disconnect()的作用是一样的
emitwarning
用于触发warnning事件,需要注册warning事件
process.on('warnning',(warning)=>{
console.warn('触发到了warning事件',warning);
})
process.emitwarning('SomeThing happend');
env
返回包含用户环境的对象,process.env用到的地方很多,比如在不同的环境下用到不同的环境变量
console.log(process.env);
// 一般我们设置NODE_ENV在process.env上来在的打包或者开发时判断环境
process.env.NODE_ENV='development'; // 如果是开发环境一般就设置development
// 如果是打包就修该他的值
//以此来区分不同的开发环境在代码中使用
execArgv
用于接收进程启动时传入的命令行选项
// 当我们在cmd/shell里输入
//node --http index.js -- versiosn
// index.js前的值会放在execArgv里
// index.js 后的值会放在argv里
console.log(process.execArgv);
console.log(process.argv);
//这个选项可以联想到 我们在cnpm 时 --save-dev 会将所下载的模块的名称写入package.json里
kill
在非windows上会发出信号,在windows上会直接找到输入的pid然后杀死该进程
//杀死子进程
// index.js 主进程
const process=require('process');
const child_process=reuqire('child_process');
const child=child_process.fork('./child.js');
child.send('HELLO ');
process.kill(child.pid,'SIGINT'); //这里的第二个参数在windows上可传可不传
//子进程
process.on('message',e=>{
console.log(e);
})
// 因为在主进程中调用kill杀死了子进程,所以子进程并不会执行message事件
memoryUsage
返回当前进程的内存使用量
console.log(process.memoryUsage());
nextTick
nextTick方法用处也是比较多的,nextTick是nodejs提供的一个异步执行函数, nextTick会在下一个事件循环前执行,他的执行顺序要优先于SetTimeout
node的什么是事件循环
nodejs的事件循环会经历一下六个阶段,在这六个阶段结束之后开启下一轮的事件循环 1. timers 阶段: 这个阶段执行 setTimeout(callback) 和 setInterval(callback) 预定的 callback; 2. I/O callbacks 阶段: 此阶段执行某些系统操作的回调,例如TCP错误的类型。 例如,如果TCP套接字在尝试连接时收到 ECONNREFUSED,则某些* nix系统希望等待报告错误。 这将操作将等待在==I/O回调阶段==执行; 3. idle, prepare 阶段: 仅node内部使用; 4. poll 阶段: 获取新的I/O事件, 例如操作读取文件等等,适当的条件下node将阻塞在这里; 5. check 阶段: 执行 setImmediate() 设定的callbacks; 6. close callbacks 阶段: 比如 socket.on(‘close’, callback) 的callback会在这个阶段执行;
代码示例
setTimeout(() => {
console.log('setTimeout1')
process.nextTick(()=>{
console.log('nextTick')
})
}, 0);
setTimeout(() => {
console.log('setTimeout2')
}, 0);
// 打印结果 setTmieout1 -> nextTick -> SetTimeout2
// 首先我们node index.js就会开启一轮事件循环 ,在代码执行中遇到SetTimeout挂起等待下一轮循环,(如果这时setTimeout时间到了会开启下一轮循环),等待两个setTimeout都被挂起第一轮的node idnex.js的时间循环就结束了,开始下一轮,会先执行setTimeout的回调,打印setTimeout1,然后遇到process.nextTick(等待下一轮事件循环开始前执行),setTimeout1打印完之后事件循环已经结束了,会执行nextTick,然后再打印setTimeout2
pid && ppid
pid: 返回当前进程的pid ppid: 返回当前进程的父pid
console.log(`this:${process.pid};parent:${parocess.ppid}`);
platform
返回操作系统平台,例如:linux就是linux windows就是win32
console.log(process.platform);
send
用于父子进程间通信
// index.js 父进程
const process=require('process');
const child_process=require('child_process');
const child=child_process.fork('./child.js');
//向子进程发送数据
child.send('data');
process.on('message',(data)=>{
console.log('父进程接收子进程的数据');
})
// child.js 子进程
process.on('message',data=>{
console.log('接收父进程数据',data);
})
process.send('向父进程发送数据');
uptime
返回当前进程运行的时间
console.log(process.uptime());
versions
返回当前node运行的版本