Programmation asynchrone Node.js
Dans la programmationsynchrone traditionnelle, le code est exécuté séquentiellement, et chaque ligne de code doit attendre que la ligne précédente ait fini de s'exécuter avant de pouvoir s'exécuter. Cependant,la programmation asynchronepermet au code de continuer à exécuter d'autres tâches en attendant que certaines opérations (telles que les opérations d'E/S) soient terminées, sans bloquer l'exécution du programme.

Node.js adopte un modèle d'E/S asynchrone, ce qui le rend particulièrement adapté à la gestion d'applications réseau à haute concurrence. Comprendre la programmation asynchrone est essentiel pour maîtriser Node.js.
Pourquoi Node.js a besoin de la programmation asynchrone
Node.js est mono-thread, ce qui signifie qu'il ne peut exécuter qu'une seule tâche à la fois. Si la programmation synchrone est utilisée, lorsqu'une opération chronophage (comme la lecture d'un fichier volumineux ou une requête réseau) est exécutée, le programme entier sera bloqué et incapable de traiter d'autres requêtes.
La programmation asynchrone résout ce problème:
- Améliore le débit des applications
- Utilise plus efficacement les ressources système
- Offre une meilleure expérience utilisateur
Trois manières principales de programmation asynchrone dans Node.js
1. Fonctions de rappel (Callbacks)
Les fonctions de rappel sont la méthode de gestion asynchrone la plus élémentaire dans Node.js. Elles fonctionnent en passant une fonction comme argument à une autre fonction, et cette fonction est appelée une fois l'opération terminée.
Exemple
// Lire le fichier de manière asynchrone
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
console.error('Erreur de lecture du fichier :', err);
return;
}
console.log('Contenu du fichier:', data);
});
console.log('Demande de lecture du fichier envoyée, poursuite de l'exécution d'un autre code...');
Fonctionnalités:
- Simple et direct
- Mène facilement à l'"enfer des callbacks"
- La gestion des erreurs n'est pas assez intuitive
2、Promise
Promise est une solution de programmation asynchrone introduite dans ES6. Elle représente l'achèvement ou l'échec éventuel d'une opération asynchrone et sa valeur résultante.
Exemple
// Lire un fichier à l'aide de Promise
fs.readFile('example.txt', 'utf8')
.then(data => {
console.log('Contenu du fichier:', data);
})
.catch(err => {
console.error('Erreur de lecture du fichier :', err);
});
console.log('Demande de lecture du fichier envoyée, poursuite de l'exécution d'un autre code...');
Fonctionnalités:
- Appels chaînés, évitant l'enfer des callbacks
- Meilleur mécanisme de gestion des erreurs
- L'état est irréversible (pending → fulfilled ou rejected)
3、async/await
async/await est du sucre syntaxique introduit dans ES8, basé sur Promise, faisant ressembler le code asynchrone à du code synchrone.
Exemple
async function readFile() {
try {
const data = await fs.readFile('example.txt', 'utf8');
console.log('Contenu du fichier:', data);
} catch (err) {
console.error('Erreur de lecture du fichier :', err);
}
}
readFile();
console.log('Demande de lecture du fichier envoyée, poursuite de l'exécution d'un autre code...');
Fonctionnalités:
- Le code est plus concis et lisible
- La gestion des erreurs utilise une structure try/catch
- Doit être utilisé dans des fonctions async
Bonnes pratiques de gestion des erreurs
Gestion des erreurs dans les fonctions de rappel
Exemple
if (err) {
console.error('Erreur de lecture du fichier :', err);
return; // Important : return après la gestion de l'erreur pour éviter d'exécuter le code suivant
}
console.log('Contenu du fichier:', data);
});
Gestion des erreurs de Promise
Exemple
.then(data => {
console.log('Contenu du fichier:', data);
return someOtherAsyncOperation(data);
})
.then(result => {
console.log('Résultat de la deuxième étape :', result);
})
.catch(err => {
console.error('Erreur lors du traitement :', err);
});
Gestion des erreurs avec async/await
Exemple
try {
const data = await fs.readFile('example.txt', 'utf8');
const result = await someOtherAsyncOperation(data);
console.log('Résultat final :', result);
} catch (err) {
console.error('Erreur lors du traitement :', err);
}
}
processData();
Considérations de performance
- Évitez de bloquer la boucle d'événements: le code synchrone de longue durée bloquera toute l'application
- Utilisez les opérations asynchrones à bon escient: Toutes les opérations n'ont pas besoin d'être asynchrones ; les tâches de calcul simples peuvent être plus efficaces avec des méthodes synchrones
- Contrôlez le degré de concurrence: Trop d'opérations asynchrones parallèles peuvent entraîner un épuisement des ressources
- Utilisez des flux pour traiter les fichiers volumineux: Pour les fichiers volumineux, utilisez des flux au lieu de les lire entièrement en une seule fois