Búsqueda de sitios web

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
    • almacena en búfer los datos (espera hasta que el proceso cierre y transfiere los datos en un solo bloque)
    • la transferencia máxima de datos hasta Node.js v.12.x era de 200 kb (por defecto), pero desde Node.js v.12.x se aumentó a 1 MB (por defecto)
  • 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 mensaje module data cada 1 segundo durante 5 segundos, porque los datos se 'transmiten'
  • el proceso hijo exec() devuelve un solo mensaje module data module data module data module data module data despué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.

Artículos relacionados