Mucha gente parece no entender cómo NodeJS de un solo subproceso puede competir con backends de múltiples subprocesos.
Para saber por qué, debemos entender qué significa realmente que Nodejs sea de un solo subproceso.
JavaScript en sí se creó originalmente para hacer cosas simples como validar formularios, dar respuestas, etc. No fue hasta 2009 que el creador de Node.js, Ryan Dahl, hizo posible escribir código del lado del servidor usando JavaScript.
Los lenguajes del lado del servidor que admiten subprocesos múltiples tienen varias estructuras y construcciones para sincronizar entre subprocesos y otras funciones orientadas a subprocesos.
Admitir estas cosas significaría que JavaScript necesitaría cambiar todo el lenguaje, lo que va en contra de las ideas de los creadores de JavaScript. Por lo tanto, para admitir subprocesos múltiples en JavaScript puro, Dahl tuvo que crear una solución alternativa. ¡Echemos un vistazo!
¿Cómo funciona Node.js?
Node.js utiliza dos tipos de subprocesos: el subproceso principal, que es manejado por el bucle de eventos, y varios subprocesos secundarios en un grupo de subprocesos de trabajo.
El mecanismo de Event Loop Node.js para manejar operaciones de E/S sin bloqueo, aunque JavaScript es de un solo subproceso, descarga operaciones al kernel del sistema cuando es posible. Cuando una operación de JavaScript bloquea un hilo, el bucle de eventos también se bloquea.
Un grupo de trabajadores es un modelo de ejecución que genera y procesa subprocesos separados, luego ejecuta tareas de forma sincrónica y devuelve los resultados al bucle de eventos. Luego, el bucle de eventos usa dicho resultado para ejecutar la devolución de llamada proporcionada.
Básicamente, el grupo de trabajadores maneja operaciones de E/S asincrónicas, principalmente interacciones con el disco y la red del sistema. Algunos módulos utilizan grupos de trabajadores listos para usar, como fs (con muchas E/S) o crypto (con muchas CPU). El grupo de trabajadores se implementa en libuv, lo que provoca un retraso leve pero casi insignificante cuando Node necesita transferir datos internamente entre JavaScript y C++.
Después de comprender el significado de bucle de eventos y grupo de trabajo, veamos el siguiente código:
En el código anterior, no tenemos que esperar el evento de forma sincrónica. Delegamos la tarea de leer el archivo al grupo de trabajadores y llamamos a la función proporcionada con el resultado. Dado que el grupo de trabajadores tiene su propio subproceso, el bucle de eventos puede continuar ejecutándose normalmente mientras se lee el archivo.
Permítanme presentarles: Workers_threads
Con el lanzamiento de Node.js 10.5.0, apareció Workers_threads. Admite la creación de aplicaciones simples de subprocesos múltiples en JavaScript.
work_threads es un paquete de módulos de nodejs. Un trabajador de subprocesos es un fragmento de código (generalmente tomado de un archivo) generado en un subproceso separado.
Es importante tener en cuenta que los términos trabajador de subprocesos, trabajador e subproceso a menudo se usan indistintamente. Todos se refieren a lo mismo.
Los subprocesos de trabajo en Node.js son útiles para realizar tareas pesadas de JavaScript. Con la ayuda de subprocesos, los trabajadores pueden ejecutar fácilmente código JavaScript en paralelo, haciéndolo más rápido y eficiente. Podemos completar tareas pesadas sin perturbar el hilo principal.
Los subprocesos de trabajo no se introdujeron en versiones anteriores de Node.js. Primero actualice su Node.js para comenzar.
Ahora cree dos archivos para implementar subprocesos de la siguiente manera:
Nombre de archivo: trabajador.js
const {workerData, parentPort} = require('worker_threads'); console.log(`Escribe cómo ${workerData} quiere relajarse con los grandes`); parentPort.postMessage({ nombre de archivo: trabajadorData, estado: 'Listo' }
Nombre de archivo: index.js
const { Trabajador } = require('worker_threads'); const runService = (datos del trabajador) => { devolver nueva Promesa((resolver, rechazar) => { trabajador constante = nuevo trabajador('./worker.js', {workerData}); trabajador.on('mensaje', resolver); trabajador.on('error', rechazar); trabajador.on('salir', (código) => { si (código! == 0) rechazar(new Error(`Worker Thread detenido con código de salida ${code}`)); }); }); }; ejecución constante = asíncrono () => { resultado constante = await runSerice('Tunde Ednut'); consola.log(resultado); }; run().catch((err) => console.error(err));
Salida: