Node多进程开发入门

Node子进程官方文档

我们在child_process中创建的进程就是Node.js的子进程;

child_process的用法:

异步:

  • exec
  • execFile
  • fork
  • spawn

同步:

  • execSync
  • execFileSync
  • spawnSync
js 复制代码
const cp = require("child_process");

child_process打印出的结果如下, 它提供了以下多种api:

异步方法

exec

exec主要是用来执行shell脚本的,exec支持3个参数command,options,callback;otpions有如下一些变量;

cwd的用法,指向上级路径,因为上级路径没有node_modules,所以不会打印出任何信息:

js 复制代码
cp.exec(
  path.resolve(__dirname, "test.shell"),
  {
    cwd: path.resolve("../"),
  },
  function (err, stdout, stderr) {
    console.log(err);
    console.log(stdout);
    console.log(stderr);
  }
);
js 复制代码
`child_process.exec(command, [options], [callback])`

我们可以通过ls打印当前文件夹的信息;

js 复制代码
// 用来执行shell脚本的
cp.exec("ls -al", function (err, stdout, stderr) {
  console.log(err);
  console.log(stdout);
  console.log(stderr);
});

err表示异常,stdout是正常执行的输出结果,stderr是异常时的输出结果;

exec加上管道符grep打印出node_modules的文件记录;

js 复制代码
// 管道符, 筛选出node_modules
cp.exec("ls -al|grep node_modules", function (err, stdout, stderr) {
  console.log(err);
  console.log(stdout);
  console.log(stderr);
});

exec也支持执行文件, 但不支持传参;

js 复制代码
// exec也支持执行文件,但不支持传参
cp.exec(path.resolve(__dirname, "test.shell"), function (err, stdout, stderr) {
  console.log(err);
  console.log(stdout);
  console.log(stderr);
});

execFile

execFile是用来执行一个文件;下面的例子ls也是指向一个文件bin/ls, execFile第二个参数是数组["-al"],它的回调函数和exec相同的;

js 复制代码
cp.execFile("ls", ["-al"], function (err, stdout, stderr) {
  console.log(err);
  console.log(stdout);
  console.log(stderr);
});

execFile中不能直接使用管道符grep,正确打开方式是shell脚本中写grep; 新建一个test.shell文件,echo $1是打印第一个参数;

js 复制代码
ls -al|grep node_modules

echo $1
js 复制代码
// __dirname是绝对路径
cp.execFile(
  path.resolve(__dirname, "test.shell"),
  ["-al"],
  function (err, stdout, stderr) {
    console.log(err);
    console.log(stdout);
    console.log(stderr);
  }
);

这时会报错,对test.shell文件得加上可执行权限;

js 复制代码
chmod =x bin/process/test.shell 
ll bin/process/test.shell

spawn

spawn支持的参数file, args入参,options;spawn没有回调;

js 复制代码
`child_process.spawn(command, [args], [options])`

spawn实现回调和打印报错;

js 复制代码
const child = cp.spawn(path.resolve(__dirname, "test.shell"), ["-al"], {
  cwd: path.resolve(".."),
});

child.stderr.on("data", function (chunk) {
  console.log("stderr--->", chunk.toString());
});

child.stdout.on("data", function (chunk) {
  console.log("stdout-->", chunk.toString());
});

spawn和exec、execFile的区别

spawn和exec、execFile都是异步执行;区别是:spawn是流式执行方式,它更适合耗时的执行任务,比如:npm的install,需要不断打印日志的;exec、execFile更是和开销比较小的任务;

js 复制代码
cnpm i -S urllib axios pkg-dir path-exists fs-extra commander npminstall user-home yargs

spawn执行cnpm install,一行行打印执行结果:

js 复制代码
const child = cp.spawn("cnpm", ["install"], {
  cwd: path.resolve("/Users/Minjie/Documents/vue3/mj-cli-new"),
});

child.stderr.on("data", function (chunk) {
  console.log(chunk.toString());
});

child.stdout.on("data", function (chunk) {
  console.log(chunk.toString());
});

用exec实现cnpm install,一次性打印出来所有结果:

js 复制代码
cp.exec(
  "cnpm install",
  { cwd: path.resolve("/Users/Minjie/Documents/vue3/mj-cli-new") },
  function (err, stdout, stderr) {
    console.log(err);
    console.log(stdout);
    console.log(stderr);
  }
);

fork

fork使用Node执行命令;

创建一个child.js文件;

js 复制代码
console.log("child process");

console.group("child pid:", process.pid);

类似于require;

js 复制代码
cp.fork(path.resolve(__dirname, "child.js"));

console.log("main pid:", process.pid);

fork和require的区别是主进程的pid和child pid不同,fork会启动子进程;

主进程和子进程可以进行通信;

js 复制代码
const child = cp.fork(path.resolve(__dirname, "child.js"));
child.send("hello child process", () => {
  // 断开
  child.disconnect();
});
console.log("main pid:", process.pid);

child.js

js 复制代码
console.log("child process");

console.group("child pid:", process.pid);

// 监听
process.on("message", (msg) => {
  console.log("msg:", msg);
});

fork适用于耗时的操作,比如下载文件;

同步方法

execSync、execFileSync

execSync打印结果不再需要回调函数,使用简单,适用于简单命令;execSync有一个隐患就是对命令的安全没有做校验;

js 复制代码
const ret = cp.execSync("ls -al|grep node_modules");
console.log("ret:", ret.toString());

const ret2 = cp.execFileSync("ls", ["-al"]);
console.log("ret2:", ret2.toString());

const ret3 = cp.spawnSync("ls", ["-al"]);
console.log("ret3:", ret3.output.toString());
相关推荐
outstanding木槿5 分钟前
react+antd的Table组件编辑单元格
前端·javascript·react.js·前端框架
好名字082143 分钟前
前端取Content-Disposition中的filename字段与解码(vue)
前端·javascript·vue.js·前端框架
隐形喷火龙1 小时前
element ui--下拉根据拼音首字母过滤
前端·vue.js·ui
m0_748241121 小时前
Selenium之Web元素定位
前端·selenium·测试工具
风无雨1 小时前
react杂乱笔记(一)
前端·笔记·react.js
鑫~阳1 小时前
快速建站(网站如何在自己的电脑里跑起来) 详细步骤 一
前端·内容管理系统cms
egekm_sefg2 小时前
webrtc学习----前端推流拉流,局域网socket版,一对多
前端·学习·webrtc
m0_748234342 小时前
前端工作中问题点拆分
前端
hans7748829682 小时前
Python入门项目:一个简单的办公自动化需求
前端·爬虫·数据分析
艾斯特_2 小时前
JavaScript甘特图 dhtmlx-gantt
前端·javascript·甘特图