前言
首先作为一名前端攻城狮,我们平时多多少少会遇到需要编写node脚本的情况,诸如: cli 编写, 文件压缩等。在执行这些任务时,不可避免的就需要使用 child_process 这个模块了。
通道
默认情况下,node.js 在父进程与子进程之间会建立 stdin、 stdout、 stderr 管道,这些管道容量有限,如果不消费输出,则使用 { stdin: 'ignore' }
创建子进程
如下 4 种方式,都可以创建子进程, 并且每一种方式都有同步创建的 api:
| api | 描述 |
|---|---|
| spawn | 启动一个子进程来执行命令 |
| exec | 衍生 shell 并在该 shell 中运行命令,完成后将 stdout 和 stderr 传给回调函数 |
| execFile | 与 [child_process.exec()] 类似,不同之处在于,默认情况下,它直接衍生命令,而不先衍生 shell。 |
| fork | 衍生新的 Node.js 进程并使用建立的 IPC 通信通道(其允许在父子进程之间发送消息)调用指定的模块 |
差异点
| api | 回调/异常 | 进程类型 | 执行类型 | 可设置超时 |
|---|---|---|---|---|
| spawn | 不支持 | 任意 | 命令 | 不支持 |
| exec | 支持 | 任意 | 命令 | 支持 |
| execFile | 支持 | 任意 | 可执行文件 | 支持 |
| fork | 不支持 | 任意 | JavaScript 文件 | 不支持 |
基本用法
spawn
- spawn 异步衍生子进程,不会阻塞 node 事件循环;
- spwnSync 同步衍生子进程,会阻塞 node 事件循环,直到衍生的进程退出为止;
import { spawn } from 'child_process'
const ls = spawn('node', ['./sorce/download.js']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
exec
语法:child_process.exec(command[, options][, callback])
exec('node ./sorce/download.js', (err, stdout, stderr) => {
console.log(stdout);
});
exec('node ./sorce/download.js', { encoding: 'utf8' } (err, stdout, stderr) => {
console.log(stdout);
});
execFile
语法:child_process.execFile(file[, args][, options][, callback])