Avant-propos
Le plus grand point fort de Nodejs est le modèle d'E/S non bloquant et piloté par les événements, ce qui confère à Nodejs de fortes capacités de traitement simultané et est très approprié pour l'écriture d'applications réseau. La plupart des opérations d'E/S dans Nodejs sont presque asynchrones, c'est-à-dire que les résultats de nos opérations d'E/S doivent essentiellement être traités dans des fonctions de rappel, comme la fonction suivante qui lit le contenu du fichier :
Alors, que devons-nous faire si nous lisons deux fichiers et fusionnons le contenu des deux fichiers pour le traitement ? La plupart des personnes qui ont été exposées à js pendant une courte période peuvent faire ceci :
Si vous faites face à plusieurs scénarios similaires, ne serait-il pas que les fonctions de rappel soient imbriquées couche par couche ? C'est ce que tout le monde appelle souvent la pyramide de rappel ou l'enfer du rappel (http://callbackhell.com/ ) est également le problème le plus gênant pour les débutants en js.
Ce type de code imbriqué pose de nombreux problèmes au développement, principalement reflétés dans :
1. La possibilité de code devient pire
2. Difficulté de débogage
3. Difficile de dépanner lorsqu'une anomalie survient
Cet article explique principalement comment gérer efficacement les problèmes de rappel asynchrone ci-dessus.
Solution de base : gérer les rappels asynchrones de manière récursive
Nous pouvons utiliser la récursivité comme outil de contrôle d'exécution de notre code. Encapsulez les opérations qui doivent être effectuées dans une fonction et contrôlez le processus d'exécution du code via des appels récursifs dans la fonction de rappel. Sans plus tarder, passons au dernier code :
.fonction parseFile() {
si (files.length == 0) {
Retour ;
>
var fichier = fichiers.shift();
fs.readFile(fichier, fonction (erreur, données) {
// Les données du fichier sont traitées ici
ParseFile(); // Après le traitement, traitez le fichier suivant via un appel récursif
});
>
//Démarrer le traitement
parseFile();
Le code ci-dessus a traité les fichiers du tableau de manière séquentielle à titre d'exemple, introduisant la méthode récursive pour contrôler le flux d'exécution du code.
Il est bon de l'appliquer à certains scénarios simples. Par exemple, nous pouvons utiliser cette méthode pour enregistrer les données d'un tableau dans la base de données en séquence.
Certains problèmes simples de rappel asynchrone peuvent être résolus par récursivité. Cependant, il est encore quelque peu incapable de gérer des rappels asynchrones complexes (comme la nécessité de synchroniser les résultats de plusieurs opérations asynchrones).
Point magnifique : utilisez des bibliothèques tierces telles que Async, Q et Promise pour gérer les rappels asynchrones
Afin de mieux gérer le problème des rappels imbriqués, vous pouvez envisager d'utiliser certaines bibliothèques tierces spécialisées dans le traitement asynchrone. Bien sûr, si vous en avez la possibilité, vous pouvez écrire votre propre outil auxiliaire pour le traitement asynchrone.
Les bibliothèques les plus couramment utilisées pour gérer le traitement asynchrone sont : async, q et promise. À en juger par le site Web npmjs.org, async est le plus populaire. J'ai déjà utilisé async, et c'est en effet très pratique. Le flux de contrôle de divers traitements asynchrones est également très bien implémenté.
Nous utiliserons async pour traiter le code initial qui lit deux fichiers en même temps. L'exemple est le suivant :
async.parallel([
fonction(rappel){
fs.readFile('/etc/passwd', fonction (erreur, données) {
Si (err) rappel(err);
rappel(null, données);
});
},
fonction(rappel){
fs.readFile('/etc/passwd2', fonction (err, data2) {
Si (err) rappel(err);
rappel(null, data2);
});
>
],
fonction (erreur, résultats) {
// Les données de data et data2 sont traitées ici, et le contenu de chaque fichier est obtenu à partir des résultats
});
Grâce au module async, le processus d'exécution asynchrone peut être bien contrôlé, ce qui peut également être considéré comme résolvant le problème des rappels à tous les niveaux. Le code est plus clair qu'avant, mais il est toujours indissociable de la fonction de rappel.
Réfléchissez-y, ne serait-il pas formidable si vous pouviez gérer le traitement asynchrone sans utiliser de fonctions de rappel ? Parlons ensuite de l'utilisation des nouvelles fonctionnalités d'ES6 pour atteindre cet objectif ?
Soyez élégant : adoptez ES6, remplacez les fonctions de rappel et résolvez le problème de l'enfer des rappels
On dit qu'EcmaScript Harmony (ES6) a introduit de nombreuses nouvelles fonctionnalités dans js. Les étudiants qui ne connaissent pas grand-chose à ES6 peuvent le consulter sur Baidu.
Pour utiliser les nouvelles fonctionnalités d'ES6 dans nodejs, vous devez utiliser la version v0.11.x ou supérieure.
Cet article présente l'utilisation des fonctionnalités de Generator pour remplacer les fonctions de rappel. Vous ne connaissez pas Generator ? Vous pouvez jeter un oeil ici.
Les deux modules co et thunkify sont utilisés ici. Vous pouvez les installer à l'aide de la commande npm install.
Prenons comme exemple le problème mentionné au début de cet article. L'exemple de code pour utiliser la fonctionnalité générateur est le suivant :
var readFile = thunkify(fs.readFile);
co(fonction *() {
var test1 = rendement readFile('test1.txt');
var test2 = rendement readFile('test2.txt');
var test = test1.toString() test2.toString();
console.log(test);
})();
La gestion des exceptions dans le code est également très simple, il suffit de faire ceci :
Ce code n’est-il pas beaucoup plus élégant ? N'est-il pas formidable de gérer du code asynchrone comme on écrit du code synchrone ?
Pour le développement Web dans le domaine de nodejs, le framework le plus populaire est express. Il convient de mentionner que TJ, un membre principal d'express, a dirigé un nouveau framework web-koa, qui est considéré comme le web de nouvelle génération. framework de développement. , koa profite vraiment de la fonctionnalité de générateur d'ES6, nous permettant d'éviter de tomber dans des couches de rappels lors du développement de systèmes Web.
Résumé
Citation d'une phrase de la promotion du projet fibjs : Less Callback, More Girls - Less callback, more girls