重学nodejs系列之process & child_process(六)

71 阅读1分钟

前言

Node.js 中的 processchild_process 模块是处理进程和子进程的关键工具,它们为在 Node.js 环境中执行各种操作提供了丰富的功能。

process 模块

1.1 基础概念

process 模块是 Node.js 的全局对象,用于访问进程相关的信息和控制进程的行为。本节将介绍一些基础概念和常见用法。

1.1.1 进程信息

通过 process 对象,我们可以获取有关当前进程的各种信息,如进程 ID、执行路径、环境变量等。

console.log(`进程 ID:${process.pid}`);
console.log(`执行路径:${process.cwd()}`);
console.log(`环境变量:${JSON.stringify(process.env)}`);

1.1.2 进程事件

process 模块还提供了一些事件,用于监听进程的不同状态和行为,如 exit 事件、uncaughtException 事件等。

process.on('exit', (code) => {
  console.log(`进程退出,退出码:${code}`);
});

process.on('uncaughtException', (err) => {
  console.error(`未捕获的异常:${err.message}`);
  process.exit(1); // 强制退出进程
});

1.2 进程控制

process 模块还允许我们控制进程的行为,如退出进程、设置进程标题等。

1.2.1 退出进程

使用 process.exit() 方法可以主动退出当前进程,同时可以传递退出码。

process.exit(); // 退出进程,退出码默认为 0
process.exit(1); // 退出进程,指定退出码为 1

1.2.2 设置进程标题

进程标题是显示在系统进程列表中的名称,可以通过 process.title 属性进行设置。

process.title = 'My Node.js App';
console.log(`进程标题:${process.title}`);

child_process 模块

2.1 执行外部命令

child_process 模块提供了 execspawn 方法,用于执行外部命令。它们之间的区别在于处理标准输入输出的方式不同。

2.1.1 使用 exec

exec 方法适用于执行简单的命令,并通过回调函数获取结果。

import { exec } from 'child_process';

exec('mkdir test', (err, stdout, stderr) => {
  if (err) {
    console.error(`执行命令出错:${err.message}`);
    return;
  }
  console.log('命令输出:', stdout);
});

2.1.2 使用 spawn

spawn 方法更适用于执行复杂的命令,它返回一个可写流对象,允许对标准输入输出进行更灵活的操作。

import { spawn } from 'child_process';

const child = spawn('tree', ['-1']);

child.stdout.on('data', (data) => {
  console.log('命令输出:', data.toString());
});

child.on('close', (code) => {
  console.log(`子进程退出,退出码:${code}`);
});

2.2 衍生子进程

fork 方法用于衍生新的 Node.js 进程,并通过 IPC(进程间通信)进行通信。这使得父子进程之间可以方便地交换消息。

import { fork }  from 'child_process';

const child = fork('child.ts');

child.on('message', (message) => {
  console.log('父进程收到消息:', message);
});

child.send({ hello: 'world' });

2.3 进程间通信

通过 child_process 模块,父子进程之间可以进行双向通信,使得它们能够共享数据。

// parent.ts
import { spawn } from 'child_process';

const child = spawn('node', ['child.js'], { stdio: 'pipe' });

child.stdout.on('data', (data) => {
  console.log('父进程收到消息:', data.toString());
});

child.stdin.write('Hello from parent!');

// 父进程收到消息: 子进程收到消息: Hello from parent!
// 父进程收到消息: Hello from child!
// child.js
process.stdin.on('data', (data) => {
  console.log('子进程收到消息:', data.toString());
  process.stdout.write('Hello from child!');
});

process & child.process还可以开发前端脚手架工具。