Maison > interface Web > js tutoriel > le corps du texte

Boucle d'événements dans Node.js : gestion des opérations asynchrones

Barbara Streisand
Libérer: 2024-10-18 22:44:03
original
997 Les gens l'ont consulté

Node.js est connu pour sa nature non bloquante et asynchrone, et la boucle d'événements est au cœur de ce comportement. Il garantit que le thread principal reste débloqué, permettant à plusieurs opérations de s'exécuter efficacement sans attendre la fin des autres. Dans cet article, nous explorerons le fonctionnement de la boucle d'événements, décomposerons ses six phases et discuterons des stratégies pour éviter de la bloquer.

Comprendre la boucle d'événements dans Node.js

La boucle d'événements dans Node.js permet un traitement asynchrone, évitant le blocage du thread principal. Il fonctionne en six phases :

Event Loop in Node.js: Managing Asynchronous Operations

Comprendre la boucle d'événement dans Node.js

La boucle d'événements est un mécanisme chargé de gérer les opérations asynchrones. Chaque fois qu'une opération telle qu'une E/S ou une minuterie se termine, la boucle d'événements détermine quand le rappel pour cette opération doit être exécuté. Cette conception permet à Node.js de traiter plusieurs requêtes sans bloquer le thread principal, garantissant ainsi des performances élevées dans les applications.

Les six phases de la boucle événementielle

La boucle événementielle fonctionne de manière cyclique, passant par six phases distinctes. Chaque phase a un objectif spécifique et les rappels sont exécutés en conséquence.

1. Phase des minuteries

Cette phase exécute les rappels programmés par setTimeout et setInterval. Si le délai spécifié a expiré, le rappel associé s'exécute ici.

Exemple :

setTimeout(() => {
  console.log('Executed after 1 second.');
}, 1000);
console.log('Timer scheduled.');
Copier après la connexion
Copier après la connexion
Copier après la connexion

Sortie :

Timer scheduled.
Executed after 1 second.
Copier après la connexion
Copier après la connexion
Copier après la connexion

Même si le délai est de 1 000 ms, setTimeout s'exécute une fois le tick de boucle de l'événement en cours terminé.

Exemple pour setInterval

let count = 0;
const intervalId = setInterval(() => {
  console.log(`Interval executed: ${++count}`);
  if (count === 3) clearInterval(intervalId);
}, 500);
Copier après la connexion
Copier après la connexion

2. Phase de rappels en attente

Dans cette phase, la boucle d'événements traite les rappels d'E/S qui ont été différés du cycle précédent. Ces rappels gèrent les erreurs et les opérations d'E/S non bloquantes.

Exemple :

const fs = require('fs');
fs.readFile('file.txt', (err, data) => {
  if (err) console.error(err);
  else console.log(data.toString());
});
Copier après la connexion
Copier après la connexion

Sortie :

Read operation scheduled.
File content:<contents of example.txt>
Copier après la connexion
Copier après la connexion

3. Idle, phase de préparation

Cette phase est utilisée en interne par Node.js pour préparer le système pour le prochain tour de sondage. Vous n'interagirez pas directement avec cette phase, mais nous pouvons simuler certains comportements qui y sont liés en nous concentrant sur des tâches telles que la configuration du sondage interne.

Exemple avec configuration du serveur TCP (état de préparation)

const net = require('net');
const server = net.createServer((socket) => {
  socket.end('Connection closed.');
});

server.listen(8080, () => {
  console.log('Server listening on port 8080.');
});
Copier après la connexion
Copier après la connexion

La phase de préparation initialise ce serveur. Une fois préparé, il passe à la phase d'interrogation en attente des connexions entrantes.

4. Phase de sondage

Pendant la phase poll, la boucle d'événements attend de nouveaux événements d'E/S et exécute les rappels pertinents. Si aucun événement n'est en attente, il restera dans cette phase jusqu'à ce qu'un nouvel événement se produise ou qu'un minuteur soit prêt à s'exécuter.

setTimeout(() => {
  console.log('Executed after 1 second.');
}, 1000);
console.log('Timer scheduled.');
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ici, le serveur entre dans la phase d'interrogation en attendant les requêtes HTTP. Lorsqu'une requête arrive, son rappel est exécuté, envoyant une réponse.

5. Vérifier la phase

La phase check exécute les rappels programmés avec setImmediate. Ces rappels sont exécutés après la phase d'interrogation, qu'il y ait ou non des opérations d'E/S en attente.

Exemple :

Timer scheduled.
Executed after 1 second.
Copier après la connexion
Copier après la connexion
Copier après la connexion

Sortie :

let count = 0;
const intervalId = setInterval(() => {
  console.log(`Interval executed: ${++count}`);
  if (count === 3) clearInterval(intervalId);
}, 500);
Copier après la connexion
Copier après la connexion

6. Fermer la phase de rappels

Cette phase gère les opérations de nettoyage. Par exemple, les rappels associés à la fermeture des connexions réseau, tels que socket.on('close'), sont exécutés ici.

const fs = require('fs');
fs.readFile('file.txt', (err, data) => {
  if (err) console.error(err);
  else console.log(data.toString());
});
Copier après la connexion
Copier après la connexion

Sortie :

Read operation scheduled.
File content:<contents of example.txt>
Copier après la connexion
Copier après la connexion

Lorsque le client se déconnecte, le rappel socket.on('close') est exécuté dans la phase de rappel de fermeture.

Bloquer la boucle d'événement

Bien que la boucle d'événements soit conçue pour gérer efficacement les opérations asynchrones, le blocage de la boucle peut dégrader les performances. Si le thread principal est bloqué par des calculs lourds ou des opérations synchrones, il empêche l'exécution d'autres rappels. Cela peut entraîner des retards et rendre votre candidature sans réponse.

Lorsque vous effectuez des tâches gourmandes en CPU (comme des calculs volumineux) sur le thread principal, cela bloque la boucle d'événements. Voici comment utiliser Worker Threads pour éviter le blocage.

Exemple de blocage de la boucle d'événement

const net = require('net');
const server = net.createServer((socket) => {
  socket.end('Connection closed.');
});

server.listen(8080, () => {
  console.log('Server listening on port 8080.');
});
Copier après la connexion
Copier après la connexion

Sortie :

const http = require('http');

const server = http.createServer((req, res) => {
  res.end('Hello from server!');
});

server.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});
Copier après la connexion

Dans cet exemple, rien d'autre ne peut s'exécuter pendant la période de blocage de 5 secondes, ce qui rend l'application insensible.

Solution : Utiliser des threads de travail

setImmediate(() => {
  console.log('Executed in check phase.');
});

setTimeout(() => {
  console.log('Executed in timers phase.');
}, 0);

console.log('Main code executed.');
Copier après la connexion

Sortie :

Main code executed.
Executed in check phase.
Executed in timers phase.
Copier après la connexion

Ici, le calcul du blocage s'exécute dans un thread séparé, laissant la boucle d'événements libre pour gérer d'autres tâches.

Comment éviter de bloquer la boucle d'événements

Utilisez les Worker Threads pour les tâches gourmandes en CPU :

Node.js fournit le module Worker Threads pour gérer des tâches telles que le traitement d'images, le cryptage ou les calculs complexes. Cela permet d'exécuter des opérations lourdes en parallèle, déchargeant ainsi le travail de la boucle d'événements.

Exemple de thread de travail :

setTimeout(() => {
  console.log('Executed after 1 second.');
}, 1000);
console.log('Timer scheduled.');
Copier après la connexion
Copier après la connexion
Copier après la connexion

Divisez les tâches volumineuses en morceaux plus petits :

Utilisez des fonctions asynchrones ou setImmediate pour diviser une tâche volumineuse en opérations plus petites et non bloquantes.

Exemple :

Timer scheduled.
Executed after 1 second.
Copier après la connexion
Copier après la connexion
Copier après la connexion

Conclusion

La boucle d'événements est un composant central de Node.js, responsable de la gestion efficace des opérations asynchrones. En comprenant ses six phases : Minuteries, Rappels en attente, Inactivité et préparation, Sondage, Vérification, et Fermer les rappels, les développeurs peuvent écrire du code non bloquant qui fonctionne correctement. Cependant, il est crucial d’éviter de bloquer la boucle d’événements avec des calculs lourds. L'utilisation d'outils tels que Worker Threads garantit que votre application reste rapide et réactive. La maîtrise de la boucle d'événements vous permettra de créer des applications Node.js évolutives et performantes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal