javascript - Node.js Spawn vs. Ejecutar
En un video de capacitación en línea que estoy viendo para aprender Node, el narrador dice que "spawn es mejor para procesos más largos que implican grandes cantidades de datos, mientras que execute es mejor para pequeños fragmentos de datos."
¿Por qué es esto? ¿Cuál es la diferencia entre las funciones spawn y exec de child_process en Node.js, y cómo sé cuál debo usar?
Respuesta #1
La principal diferencia es que spawn es más adecuado para procesos de larga duración con una salida enorme. Esto se debe a que spawn transmite la entrada/salida con un proceso hijo. Por otro lado, exec almacena la salida en un búfer pequeño (por defecto 1MB, 200 KB hasta la versión v11.x). exec primero crea un subshell y luego intenta ejecutar tu proceso. Para resumir, usa spawn en caso de que necesites que se transmitan muchos datos desde un proceso hijo y exec si necesitas características como tuberías del shell, redireccionamientos o incluso más de un programa al mismo tiempo.
Algunos enlaces útiles - DZone Hacksparrow
Respuesta #2
proceso hijo creado por
spawn()- no genera una shell
- transmite los datos devueltos por el proceso hijo (el flujo de datos es constante)
- no tiene límite de tamaño de transferencia de datos
proceso hijo creado por exec()
- genera un shell en el que se ejecuta el comando pasado
main.js (archivo)
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);
});
- module.js (básicamente devuelve un mensaje cada segundo durante 5 segundos y luego sale)
let interval = setInterval(function () {
console.log("module data");
if (interval._idleStart > 5000) clearInterval(interval);
}, 1000);
- el proceso hijo
spawn()devuelve el mensajemodule datacada 1 segundo durante 5 segundos, porque los datos se 'transmiten' - el proceso hijo
exec()devuelve un solo mensajemodule data module data module data module data module datadespués de 5 segundos (cuando el proceso se cierra) esto se debe a que los datos están 'en búfer'
NOTA que ni los procesos hijos spawn() ni exec() están diseñados para ejecutar módulos de Node, esta demostración es solo para mostrar la diferencia, (si quieres ejecutar módulos de Node como procesos hijos usa el método fork() en su lugar)
Respuesta #3
Un buen lugar para empezar es la documentación de NodeJS.
Para 'spawn', la documentación indica:
El método child_process.spawn() crea un nuevo proceso usando el comando dado, con argumentos de línea de comandos en args. Si se omite, args por defecto es un arreglo vacío.
Mientras que para 'exec':
Genera un shell y luego ejecuta el comando dentro de ese shell, almacenando en búfer cualquier salida generada. La cadena de comando pasada a la función exec es procesada directamente por el shell y los caracteres especiales (que varían según el shell) deben ser manejados en consecuencia.
Lo principal parece ser si necesitas manejar la salida del comando o no, lo cual imagino que podría ser el factor que afecta el rendimiento (no he comparado). Si solo te importa la finalización del proceso, entonces 'exec' sería tu elección. Spawn abre flujos para stdout y stderr con eventos ondata, exec solo devuelve un búfer con stdout y stderr como cadenas.
