Node.js 子进程:child_process

概述

Node.js 基于单线程事件循环模型,------当遇到 CPU 密集型任务(如大规模数学计算、图像/视频处理、文件压缩等)时,单个线程会被阻塞,导致整个应用停滞不前,无法处理其他请求。

child_process 模块正是 Node.js 为我们提供的,用于跳出单线程限制、真正利用多核 CPU 性能的强大武器。它允许你创建并管理子进程,从而执行系统命令、运行其他脚本或可执行文件,实现并行处理。

简单来说,child_process 能够在 Node.js 程序中"开小号",让多个任务同时进行,极大地提升了程序的性能。

核心 API

child_process 模块提供了四种主要方法来创建子进,适用于不同的场景。

1. exec:执行 Shell 命令

exec 方法用于执行一个 Shell 命令 。它会启动一个 Shell(如 /bin/sh on Unix,cmd.exe on Windows)来解析命令,这意味着你可以使用管道 |、重定向 > 等 Shell 特性。

它的特点是缓冲输出 ,即会等待命令完全执行完毕,然后将所有输出一次性返回给你。

javascript 复制代码
const { exec } = require('child_process');

// 执行 git status 命令
exec('git status', (error, stdout, stderr) => {
  if (error) {
    console.error(`执行出错: ${error.message}`);
    return;
  }
  if (stderr) {
    console.error(`标准错误: ${stderr}`);
    return;
  }
  console.log(`标准输出: ${stdout}`);
});

适用场景

  • 执行简单的、输出量不大的 Shell 命令,并获取最终结果。例如,获取项目 git 状态、检查磁盘空间 (df -h) 等。

2. spawn:流式处理

spawn不启动一个 Shell ,而是直接衍生一个新的进程 来执行指定的命令。它通过流(Stream) 的方式返回子进程的 stdoutstderr

这意味着你可以实时地接收到输出数据块,而不是等到命令结束。这对于处理大量数据(如处理大文件、长日志)至关重要,因为内存占用小,效率高。

javascript 复制代码
const { spawn } = require('child_process');

// 使用 spawn 执行 find 命令,查找所有 .js 文件
const child = spawn('find', ['.', '-name', '*.js']);

// 实时接收数据
child.stdout.on('data', (data) => {
  console.log(`找到文件: ${data}`);
});

child.stderr.on('data', (data) => {
  console.error(`错误: ${data}`);
});

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

适用场景

  • 处理大量输出 :如 npm installdocker build 等需要实时查看进度的命令。

3. execFile:二进制执行

execFileexec 类似,但它不启动 Shell 。它直接执行一个可执行文件 。这使得它比 exec 效率稍高,而且更安全 (因为它避免了潜在的 Shell 注入攻击)。但它不能使用 Shell 的原语,如通配符 * 或管道 |

javascript 复制代码
const { execFile } = require('child_process');

// 直接执行 node 可执行文件,并传递参数
execFile('node', ['--version'], (error, stdout, stderr) => {
  if (error) {
    throw error;
  }
  console.log(stdout); // v18.x.x
});

适用场景:运行已知的、不需要 Shell 特性的二进制文件或脚本,追求更高的安全性和效率。

总结

方法 核心特点 输出处理 典型使用场景
exec 使用 Shell 缓冲 简单的 Shell 命令,输出量小
spawn 不使用 Shell,高效 流式 (Stream) 需要实时输出、处理大量数据
execFile 不使用 Shell,安全 缓冲 执行已知的二进制可执行文件

上面的几个方法在项目工程化开发插件、提供开发工具、规范、文件输出、脚手架改造的时候比较常用。

相关推荐
mCell2 小时前
GSAP ScrollTrigger 详解
前端·javascript·动效
excel5 小时前
为什么在 Three.js 中平面能产生“起伏效果”?
前端
excel6 小时前
Node.js 断言与测试框架示例对比
前端
天蓝色的鱼鱼7 小时前
前端开发者的组件设计之痛:为什么我的组件总是难以维护?
前端·react.js
codingandsleeping7 小时前
使用orval自动拉取swagger文档并生成ts接口
前端·javascript
石金龙8 小时前
[译] Composition in CSS
前端·css
白水清风8 小时前
微前端学习记录(qiankun、wujie、micro-app)
前端·javascript·前端工程化
Ticnix9 小时前
函数封装实现Echarts多表渲染/叠加渲染
前端·echarts
用户22152044278009 小时前
new、原型和原型链浅析
前端·javascript