在我观看学习 Node 的在线培训视频中,旁白说“spawn 对于涉及大量数据的较长进程更好,而执行对于短数据位更好。”
这是为什么呢? Node.js 中的 child_process 生成函数和执行函数有什么区别?我什么时候知道该使用哪一个?
主要区别在于
spawn
更适合长时间运行且输出巨大的流程。这是因为 spawn
使用子进程流式传输输入/输出。另一方面,exec
将输出缓冲在一个小缓冲区(默认为 1MB,v11.x 之前为 200 KB)。 exec
首先生成一个子 shell,然后尝试执行您的进程。长话短说,如果您需要从子进程流式传输大量数据,请使用 spawn
;如果您需要 shell 管道、重定向甚至一次多个程序等功能,请使用 exec
。
一些有用的链接 - DZone Hacksparrow
由
spawn()
创建的子进程
由
exec()
创建的子进程
main.js(文件)
const { spawn, exec } = require("child_process");
// 'node' is an executable command (can be executed without a shell)
// uses streams to transfer data (spawn.stout)
const process = spawn("node", ["module.js"]);
process.stdout.on("data", function (msg) {
console.log(msg.toString());
});
// the 'node module.js' runs in the spawned shell
// transfered data is handled in the callback function
exec("node module.js", function (err, stdout, stderr) {
console.log(stdout);
});
let interval = setInterval(function () {
console.log("module data");
if (interval._idleStart > 5000) clearInterval(interval);
}, 1000);
spawn()
子进程每 1 秒返回一次消息module data
,持续 5 秒,因为数据是“流式传输”的exec()
子进程仅在5秒后(进程关闭时)返回一条消息module data module data module data module data module data
,这是因为数据已“缓冲”注意,
spawn()
和exec()
子进程都不是为运行节点模块而设计的,这个演示只是为了展示差异,(如果你想将节点模块作为子进程运行,请使用fork()
方法)
NodeJS 文档是一个不错的起点。
对于“生成”,文档状态:
child_process.spawn() 方法使用给定的命令生成一个新进程,并在 args 中使用命令行参数。如果省略,args 默认为空数组。
对于“执行”:
生成一个 shell,然后在该 shell 中执行命令,缓冲任何生成的输出。传递给 exec 函数的命令字符串由 shell 直接处理,特殊字符(根据 shell 不同)需要进行相应的处理。
主要的事情似乎是您是否需要处理命令的输出,我想这可能是影响性能的因素(我没有比较)。如果您只关心流程完成,那么“exec”将是您的选择。 Spawn 使用 ondata 事件打开 stdout 和 stderr 的流,exec 仅返回一个以 stdout 和 stderr 作为字符串的缓冲区。
引用官方文档:
为了方便起见,
模块提供了一些child_process
和child_process.spawn()
的同步和异步替代方案。这些替代方案中的每一个都是在child_process.spawnSync()
或child_process.spawn()
之上实现的。child_process.spawnSync()