Node.js Spawn与执行

Har*_*mer 11 javascript function spawn node.js

在观看我学习Node的在线培训视频中,讲述者说:“对于包含大量数据的较长流程而言,生成更好,而对于短数据则执行效果更好。”

为什么是这样?Node.js中child_process生成和执行函数之间有什么区别,我何时知道要使用哪个?

Pal*_*pad 35

  • child process created by spawn()

    • does not spawn a shell
    • streams the data returned by the child process (data flow is constant)
    • has no data transfer size limit
  • child process created by exec()

    • does spawn a shell in which the passed command is executed
    • buffers the data (waits till the process closes and transfers the data in on chunk)
    • maximum data transfer 200kb (by default)

-main.js (file)

var {spawn, exec} = require('child_process');

    // 'node' is an executable command (can be executed without a shell) 
    // uses streams to transfer data (spawn.stout)  
var spawn = spawn('node', ['module.js']);     
spawn.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 
var exec = exec('node module.js', function(err, stdout, stderr){
    console.log(stdout);
});
Run Code Online (Sandbox Code Playgroud)

-module.js (baiscally returns a message every second for 5 seconds than exits)

var interval;
interval = setInterval(function(){
    console.log( 'module data' );
    if(interval._idleStart > 5000) clearInterval(interval);
}, 1000);
Run Code Online (Sandbox Code Playgroud)
  • the spawn() child process returns the message module data every 1 second for 5 seconds, because the data is 'streamed'
  • the exec() child process returns one message only module data module data module data module data module data after 5 seconds (when the process is closed) this is because the data is 'buffered'

NOTE that neither the spawn() nor the exec() child processes are designed for running node modules, this demo is just for showing the difference, (if you want to run node modules as child processes use the fork() method instead)

  • 附带说明一下,避免执行“var spawn = spawn(...)”和“var exec = exec(...)”,因为这会覆盖函数。 (7认同)

Vas*_*lov 11

主要区别在于spawn它更适合长时间运行且产量巨大的过程。spawn通过子进程流输入/输出。exec缓冲的输出放在一个小的(默认为200K)缓冲区中。而且据我所知,exec首先生成子外壳,然后尝试执行您的过程。为了避免长话短说spawn,以防万一您需要从子进程中传输大量数据,并且exec需要诸如外壳程序管道,重定向之类的功能,甚至需要一次执行多个程序。

一些有用的链接- DZone Hacksparrow

  • @Zhou,您可以使用从“exec”返回的 ChildProcess 对象,类似于从“spawn”使用它,但是,这会有点违背使用“exec”的目的,因为该函数抽象了处理流的需要。但在幕后,这些流仍然存在,“exec”只是为您收集其中的数据。您发现的是,在使用“exec”时,这些流在技术上仍然可供您使用。然而,通常并不真正需要它们。 (2认同)

And*_*e M 9

一个很好的起点是NodeJS 文档

对于“生成”文档状态:

child_process.spawn()方法使用给定命令在args中带有命令行参数来生成新进程。如果省略,则args默认为空数组。

而对于“ exec”:

生成一个shell,然后在该shell中执行命令,缓冲任何生成的输出。传递给exec函数的命令字符串由shell直接处理,特殊字符(基于shell的不同)需要相应地处理。

主要的事情似乎是您是否需要处理命令的输出,我想这可能是影响性能的因素(我没有比较过)。如果只关心流程完成而不是输出,那么“ spawn”就足够了。

  • 我认为“NodeJS 是一个很好的起点”。我刚刚开始,无法过滤掉差异,太大的文字墙对我打击很大。我读过一篇文章,向下滚动并忘记了我读过的内容。我知道RTFM为王,但是FM阅读应该更人性化 (8认同)
  • 同意@Marecky。Nodejs 文档就像一本字典:对单个元素有很好的参考,但不太适合突出相似元素之间的差异。 (3认同)
  • 该答案的最后一行应为:如果您只关心流程完成,那么“ exec”将是您的选择。Spawn使用ondata事件为stdout和stderr打开流,exec只是返回带有stdout和stderr作为字符串的缓冲区。 (2认同)