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());
相关推荐
让开,我要吃人了2 小时前
HarmonyOS开发实战(5.0)实现二楼上划进入首页效果详解
前端·华为·程序员·移动开发·harmonyos·鸿蒙·鸿蒙系统
everyStudy3 小时前
前端五种排序
前端·算法·排序算法
甜兒.5 小时前
鸿蒙小技巧
前端·华为·typescript·harmonyos
Jiaberrr8 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy8 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白8 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、8 小时前
Web Worker 简单使用
前端
web_learning_3218 小时前
信息收集常用指令
前端·搜索引擎
tabzzz9 小时前
Webpack 概念速通:从入门到掌握构建工具的精髓
前端·webpack
200不是二百9 小时前
Vuex详解
前端·javascript·vue.js