Module Domain de Node.js

Java FileModules intégrés de Node.js


Le module Domain est un outil dans Node.js pour simplifier la gestion des erreurs dans le code asynchrone. Il vous permet de regrouper plusieurs opérations asynchrones dans un "domain" et de capturer et gérer uniformément les erreurs au sein de ce domaine.

En termes simples, Domain est comme un "conteneur" de gestion des erreurs. Vous pouvez placer des opérations asynchrones liées dans ce conteneur, puis gérer uniformément les erreurs susceptibles de survenir dans ces opérations.

L'utilisation du module domain est dépréciée dans Node.js 14, car la communauté Node.js recommande des méthodes plus modernes pour gérer les erreurs, comme l'utilisation d'async/await ou d'une logique plus complète d'écoute et de gestion des erreurs.


Pourquoi avez-vous besoin du module Domain ?

Dans la programmation asynchrone Node.js, la gestion des erreurs peut devenir complexe :

  1. Les erreurs asynchrones sont difficiles à intercepter: Le try-catch traditionnel ne peut pas intercepter les erreurs dans les callbacks asynchrones
  2. La propagation des erreurs est difficile: Les erreurs peuvent se produire dans n'importe quelle opération asynchrone, ce qui rend difficile l'identification de la source
  3. Problèmes de nettoyage des ressources: Après la survenue d'une erreur, vous devez vous assurer que les ressources sont libérées correctement

Le module Domain est conçu pour résoudre ces problèmes.


Concepts fondamentaux du module Domain

1. Création d'un Domain

Exemple

const domain = require('domain');
const myDomain = domain.create();

2. Cycle de vie d'un Domain

  1. Création: Utiliserdomain.create()
  2. Entrée: Utiliserdomain.enter()ou entrer implicitement
  3. Exécution: exécuter du code dans le domaine
  4. Sortie: utiliserdomain.exit()
  5. Destruction: automatiquement détruit lorsqu'il n'y a plus de références

3. Liaison implicite

Un Domain peut être implicitement lié aux objets suivants :

  • setTimeout/setIntervalFonctions de rappel
  • Événements EventEmitter
  • Opérations sur les flux

Méthodes principales de Domain

1. domain.run(fn)

Exécuter une fonction dans le contexte du domaine :

Exemple

myDomain.run(() => {
  // Les opérations asynchrones ici seront interceptées par le domain
  setTimeout(() => {
    throw new Error('Async error');
  }, 100);
});

2. domain.add(emitter)

Ajoutez explicitement une instance EventEmitter au domain :

Exemple

const server = require('http').createServer();
myDomain.add(server);

3. domain.remove(emitter)

Supprimez une instance EventEmitter du domain.

4. domain.bind(callback)

Renvoie une nouvelle fonction liée au domain :

Exemple

const boundFn = myDomain.bind((err, data) => {
  if (err) throw err;
  console.log(data);
});

5. domain.intercept(callback)

Similaire à bind, mais gère spécifiquement les callbacks error-first:

Exemple

const interceptedFn = myDomain.intercept((err, data) => {
  console.log(data);
});

Gestion des erreurs

Domain gère les erreurs capturées viaerrorl'événement error:

Exemple

myDomain.on('error', (err) => {
  console.error('Domain caught error:', err);
  // Nettoyer les ressources
  server.close();
});

Exemples d’application pratique

1. Gestion des erreurs du serveur HTTP

Exemple

const http = require('http');
const domain = require('domain');

const server = http.createServer((req, res) => {
  const d = domain.create();
 
  d.on('error', (err) => {
    res.statusCode = 500;
    res.end(`Server error: ${err.message}`);
    // Empêcher le plantage du processus
    server.close();
  });
 
  d.run(() => {
    // Gérer la requête
    process.nextTick(() => {
      // Simuler une erreur asynchrone
      if (req.url === '/error') {
        throw new Error('Erreur intentionnelle');
      }
      res.end('OK');
    });
  });
});

server.listen(3000);

2. Gestion des connexions à la base de données

Exemple

const domain = require('domain');
const db = require('some-db-library');

function queryDatabase(callback) {
  const d = domain.create();
 
  d.on('error', (err) => {
    console.error('Erreur de base de données :', err);
    db.releaseConnection();
  });
 
  d.run(() => {
    db.getConnection((err, connection) => {
      if (err) throw err;
     
      connection.query('SELECT * FROM users', (err, results) => {
        if (err) throw err;
        callback(null, results);
        db.releaseConnection();
      });
    });
  });
}

Limites de Domain

  1. Déprécié: Node.js a officiellement déprécié le module domain ; il est recommandé d'utiliser async_hooks ou d'autres méthodes
  2. Fuites de mémoire: Une utilisation incorrecte peut entraîner des fuites de mémoire
  3. Surcoût de performance: La création et la gestion de domaines entraînent un certain surcoût de performance

Alternatives

Étant donné que le module domain a été déprécié, envisagez les alternatives suivantes :

  1. async/await + try-catch: Utilisez des méthodes modernes de traitement asynchrone en JavaScript
  2. Gestion des erreurs Promise: Utilisez.catch()pour gérer les erreurs dans les chaînes Promise
  3. async_hooks: Une API de suivi de contexte asynchrone de plus bas niveau fournie par Node.js

Méthodes et propriétés

Méthode/PropriétéDescription
domain.create()Créer et renvoyer un nouveaudomaininstance.
domain.run(callback)Exécuter la fonction de rappel fournie dans le domaine, en interceptant automatiquement les erreurs dans la fonction de rappel.
domain.bind(callback)Créer une nouvelle fonction qui appelle la fonction d'origine, tout en interceptant toute erreur levée.
domain.intercept(callback)Similaire àbind(), mais transmet l'erreur comme premier argument à la fonction de rappel.
domain.add(emitter)Ajouter explicitement un objet EventEmitter ou Timer afin que ses erreurs soient interceptées par le domaine actuel.
domain.remove(emitter)Supprimer l'objet EventEmitter ou Timer spécifié du domaine.
domain.on('error', callback)Écouter l'événement du domaineerror, en interceptant toutes les erreurs non gérées.

Exemple

1. Créer un domaine et utiliser domain.run() pour intercepter les erreurs

domain.run() peut placer des opérations asynchrones dans le domaine ; si une erreur se produit dans l'opération, elle sera interceptée et gérée par le domaine actuel.

Exemple

const domain = require('domain');
const d = domain.create();

d.on('error', (err) => {
  console.log('Erreur interceptée :', err);
});

d.run(() => {
  setTimeout(() => {
    throw new Error('Erreur asynchrone');
  }, 100);
});

Dans l'exemple ci-dessus, l'erreur dans setTimeout est capturée par l'événement error du domaine, sans provoquer le plantage du processus.

2. Utilisez domain.bind() pour intercepter les erreurs dans les callbacks

domain.bind() crée une fonction d'encapsulation qui peut intercepter les erreurs de la fonction de rappel dans le domaine courant.

Exemple

const domain = require('domain');
const d = domain.create();

d.on('error', (err) => {
  console.log('Erreur interceptée :', err);
});

const asyncFunction = d.bind((callback) => {
  setTimeout(() => {
    callback(new Error('Error in callback'));
  }, 100);
});

asyncFunction((err) => {
  if (err) throw err;
});

Ici, l'erreur dans asyncFunction sera interceptée et gérée par le domaine.

3. Utilisez domain.add() pour ajouter explicitement des événements

Vous pouvez utiliser domain.add() pour ajouter un EventEmitter spécifique au domaine, afin que ses erreurs soient également interceptées par le domaine.

Exemple

const domain = require('domain');
const EventEmitter = require('events');
const d = domain.create();

const emitter = new EventEmitter();

d.on('error', (err) => {
  console.log('Caught EventEmitter error:', err);
});

// Ajouter emitter au domaine
d.add(emitter);

emitter.on('data', () => {
  throw new Error('Error in EventEmitter');
});

emitter.emit('data');

Lorsque l'événement data lève une erreur, le domain intercepte cette erreur sans provoquer le plantage du programme.

Notes et limitations de domain

  • Impact sur les performances:domainCela aura un certain impact sur les performances, en particulier dans les scénarios à forte concurrence, donc une utilisation fréquente n'est pas recommandée.
  • Non recommandé pour une utilisation dans de nouveaux projets: Depuis Node.js 4.0,domaina été marqué comme un module obsolète. Pour les nouveaux projets, il est recommandé d'utiliser des méthodes de gestion des erreurs plus modernes, telles queasync/await、try/catchet les écouteurs d'événements, etc.
  • Ne convient pas à tous les scénarios:domainIl ne peut pas intercepter tous les types d'erreurs (comme les erreurs de syntaxe) ; il ne convient qu'à la gestion des erreurs d'exécution dans les opérations asynchrones et les fonctions de rappel.

Alternatives

Puisquedomaina été déprécié, il est recommandé d'utiliser les méthodes suivantes pour gérer les erreurs dans les opérations asynchrones :

  • Utiliserasync/awaitettry/catch: Pour les fonctions qui prennent en charge async/await, les erreurs peuvent être interceptées viatry/catch.
  • Gestion globale des erreurs: Vous pouvez utiliserprocess.on('uncaughtException')etprocess.on('unhandledRejection')pour écouter les exceptions non capturées et les rejets de Promise non gérés.
  • Gestion des erreurs pour les écouteurs d'événements: Ajoutez un écouteur à chaque EventEmittererrorévénement.

Bien quedomainLe module offre un moyen pratique d'intercepter les erreurs dans les opérations asynchrones, mais en raison de problèmes de performance et de fiabilité, Node.js ne recommande pas officiellement de l'utiliser dans de nouveaux projets. Pour la gestion des exceptions, il est recommandé d'utiliser des solutions plus modernes, telles queasync/awaitet les écouteurs d'événements pour garantir que les erreurs peuvent être gérées efficacement dans l'application.

Java FileModules intégrés de Node.js

Autres extensions