Beaucoup de gens ne semblent pas comprendre comment NodeJS monothread peut rivaliser avec les backends multithread.
Pour savoir pourquoi, nous devons comprendre ce que signifie réellement le fait que Nodejs soit monothread.
JavaScript lui-même a été créé à l'origine pour faire des choses simples comme valider des formulaires, créer des réponses, etc. Ce n'est qu'en 2009 que le créateur de Node.js, Ryan Dahl, a rendu possible l'écriture de code côté serveur à l'aide de JavaScript.
Les langages côté serveur qui prennent en charge le multithreading ont diverses structures et constructions pour la synchronisation entre les threads et d'autres fonctionnalités orientées thread.
Prendre en charge ces éléments signifierait que JavaScript devrait modifier l'intégralité du langage, ce qui va à l'encontre des idées des créateurs de JavaScript. Par conséquent, afin de prendre en charge le multithreading en JavaScript pur, Dahl a dû créer une solution de contournement. Jetons un coup d'oeil !
Comment fonctionne Node.js ?
Node.js utilise deux types de threads : le thread principal, qui est géré par la boucle d'événements, et plusieurs threads secondaires dans un pool de threads de travail.
Le mécanisme d' Event Loop Node.js pour gérer les opérations d'E/S non bloquantes, même si JavaScript est monothread, décharge les opérations sur le noyau du système lorsque cela est possible. Lorsqu'une opération JavaScript bloque un thread, la boucle d'événements est également bloquée.
Un pool de tâches est un modèle d'exécution qui génère et traite des threads séparés, puis exécute les tâches de manière synchrone et renvoie les résultats à la boucle d'événements. La boucle d'événements utilise ensuite ledit résultat pour exécuter le rappel fourni.
Fondamentalement, le pool de tâches gère les opérations d'E/S asynchrones, principalement les interactions avec le disque système et le réseau. Certains modules utilisent des pools de tâches prêts à l'emploi, tels que fs (lourd en E/S) ou crypto (lourd en CPU). Le pool de travailleurs est implémenté dans libuv, ce qui entraîne un délai léger mais presque négligeable lorsque Node doit transférer des données en interne entre JavaScript et C++.
Après avoir compris la signification de la boucle d'événements et du pool de travail, examinons le code suivant :
Dans le code ci-dessus, nous n'avons pas besoin d'attendre l'événement de manière synchrone. Nous déléguons la tâche de lecture du fichier au pool de travailleurs et appelons la fonction fournie avec le résultat. Étant donné que le pool de travailleurs possède son propre thread, la boucle d'événements peut continuer à s'exécuter normalement pendant la lecture du fichier.
Laissez-moi vous présenter : worker_threads
Avec la sortie de Node.js 10.5.0, worker_threads est apparu. Il prend en charge la création d'applications multithread simples en JavaScript.
worker_threads est un package de module nodejs. Un thread worker est un morceau de code (généralement extrait d'un fichier) généré dans un thread séparé.
Il est important de noter que les termes thread travailleur, travailleur et thread sont souvent utilisés de manière interchangeable. Ils font tous référence à la même chose.
Les threads de travail dans Node.js sont utiles pour effectuer des tâches JavaScript lourdes. À l'aide de threads, Workers peut facilement exécuter du code JavaScript en parallèle, ce qui le rend plus rapide et plus efficace. Nous pouvons effectuer des tâches lourdes sans perturber le fil principal.
Les threads de travail n'ont pas été introduits dans les anciennes versions de Node.js. Alors commencez par mettre à jour votre Node.js pour commencer.
Créez maintenant deux fichiers pour implémenter les threads comme suit :
Nom du fichier : worker.js
const { workerData, parentPort } = require('worker_threads'); console.log(`Écrivez sur la façon dont ${workerData} veut se détendre avec les grands`); parentPort.postMessage({ nom de fichier : workerData, statut : 'Terminé' });
Nom de fichier : index.js
const { Worker } = require('worker_threads'); const runSerice = (workerData) => { renvoyer une nouvelle promesse ((résoudre, rejeter) => { const travailleur = new Worker('./worker.js', { workerData }); travailleur.on('message', résolution); travailleur.on('erreur', rejet); travailleur.on('sortie', (code) => { si (code !== 0) rejeter(nouvelle erreur(`Worker Thread arrêté avec le code de sortie ${code}`)); }); }); } ; const run = async () => { const result = wait runSerice('Tunde Ednut'); console.log(résultat); } ; run().catch((err) => console.error(err))
;