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

Utiliser Promise pour encapsuler des fonctions asynchrones dans NodeJS_node.js

WBOY
Libérer: 2016-05-16 16:13:00
original
1101 Les gens l'ont consulté

Dans le processus d'écriture de Node.js, les opérations d'E/S continues peuvent conduire à un "cauchemar pyramidal". L'imbrication multiple des fonctions de rappel rend le code difficile à maintenir. Utilisez la promesse de CommonJs pour encapsuler des fonctions asynchrones et utiliser une API en chaîne unifiée. pour se débarrasser du cauchemar des rappels multiples.

Le modèle IO non bloquant fourni par Node.js nous permet d'utiliser des fonctions de rappel pour gérer les opérations IO. Cependant, lorsque des opérations IO continues sont requises, vos fonctions de rappel seront imbriquées plusieurs fois, ce qui rendra le code très inesthétique et difficile. à maintenir. Et il peut y avoir beaucoup de code en double pour la gestion des erreurs, ce qu'on appelle la "Pyramide du Destin".

Copier le code Le code est le suivant :

étape1(fonction (valeur1) {
Étape 2 (valeur 1, fonction (valeur 2) {
         step3(valeur2, fonction(valeur3) {
              step4(value3, function(value4) {
// Faire quelque chose avec value4
            });
        });
});
});

Il s'agit en fait d'un problème avec le flux de contrôle de Node.js. Il existe de nombreuses solutions à ce problème, comme l'utilisation d'async, ou d'eventProxy, etc. Cependant, le thème de cet article est d'utiliser Promise dans la spécification CommonJs pour résoudre ce problème. problème.

Qu'est-ce que la promesse ?

Il existe de nombreuses spécifications Promise de CommonJs. Nous discutons généralement de la spécification Promise/A, qui définit le comportement de base de Promise.

Une promesse est un objet qui représente généralement une opération asynchrone qui pourrait être complétée dans le futur. Cette opération peut réussir ou échouer, donc un objet Promise a généralement trois états : En attente, Réalisé et Rejeté. Représente respectivement une réalisation incomplète, une réussite et un échec de l'opération. Une fois que l’état de l’objet Promise passe de En attente à Réalisé ou Rejeté, son état ne peut plus être modifié.

Un objet Promise a généralement une méthode then, qui nous permet de manipuler la valeur renvoyée après un éventuel succès dans le futur ou la raison de l'échec. La méthode then ressemble à ceci :

promise.then(onFulfilled, onRejected)
Évidemment, la méthode then accepte deux paramètres, qui sont généralement deux fonctions. L'une est utilisée pour gérer les résultats après la réussite de l'opération, et l'autre est utilisée pour gérer les raisons après l'échec de l'opération. La première de ces deux fonctions Les deux paramètres. sont respectivement le résultat après le succès et la raison de l'échec. Si le paramètre passé à la méthode then n'est pas une fonction, ce paramètre sera ignoré.

La valeur de retour de la méthode then est un objet Promise. Cette fonctionnalité nous permet d'enchaîner les appels puis pour obtenir l'effet de contrôler le flux. Il existe de nombreux problèmes détaillés ici, tels que le transfert de valeur ou la gestion des erreurs. La spécification de Promise est définie comme suit :

La valeur de retour de la fonction onFulfilled ou onRejected n'est pas un objet Promise, alors cette valeur sera utilisée comme premier paramètre de onFulfilled dans la méthode then suivante. Si la valeur de retour est un objet Promise, pourquoi la valeur de retour. de la méthode then l'objet Promise
Si une exception est levée dans la fonction onFulfilled ou onRejected, le statut de l'objet Promise renvoyé par la méthode then sera remplacé par Rejected. Si l'objet Promise appelle then, l'objet Error sera utilisé comme premier paramètre de la fonction onRejected.
Si le statut Promise devient Fulfilled et qu'aucune fonction onFulfilled n'est fournie dans la méthode then, le statut de l'objet Promise renvoyé par la méthode then devient Fulfilled et le résultat réussi est le résultat de la promesse précédente. Il en va de même pour Rejected.
De plus, onFulfilled et onRejected sont exécutés de manière asynchrone.

Implémentation standard : q

Ce qui précède est la spécification de Promise, et ce dont nous avons besoin, c'est de son implémentation. q est une bibliothèque avec de meilleures spécifications d'implémentation pour Promise/A.

Nous devons d'abord créer un objet Promise. Les spécifications pour la création d'objets Promise sont dans Promise/B. Je ne donnerai pas d'explication détaillée ici, allez simplement au code.

Copier le code Le code est le suivant :

Fonction(drapeau){
         var defer = q.defer();
             fs.readFile("a.txt", function(err, data){
Si(err) reporter.reject(err);
                 else defer.resolve(data);
            });
                return defer.promise;
>

La plupart des implémentations de Promise sont similaires dans la création de Promise. En créant un objet defer avec un attribut de promesse, si la valeur est obtenue avec succès, defer.resolve(value) est appelé en cas d'échec, defer.reject(reason. ) est appelé. Enfin, renvoyez l’attribut promise de defer. Ce processus peut être compris comme l'appel de defer.resolve pour changer le statut de la promesse en Réalisé, et l'appel de defer.reject pour changer le statut de la promesse en Rejeté.

Face à une série de méthodes asynchrones continues, comment utiliser Promise pour écrire du beau code ? Jetez un œil à l’exemple ci-dessous.

Copier le code Le code est le suivant :

promesse0.then(fonction(résultat){
              // faire quelque chose
        renvoyer le résultat ;
}).then(function(result) {
              // faire quelque chose
          promesse de retour 1 ;                                          }).then(function(result) {
              // faire quelque chose
}).catch(function(ex) {
console.log(ex);
}).finally(function(){
console.log("final");
});

Dans le code ci-dessus, la méthode then n'accepte que OnFulfilled, et la méthode catch est en fait then(null, OnRejected). Dans ce cas, tant qu'une série de méthodes asynchrones renvoient toujours des valeurs avec succès, le code le fera. être de style cascade. En cours d'exécution vers le bas, si l'une des méthodes asynchrones échoue ou qu'une exception se produit, alors, selon la spécification CommonJs Promise, la fonction dans le catch sera exécutée. q fournit également la méthode final, qui est facile à comprendre littéralement, c'est-à-dire que, indépendamment de la résolution ou du rejet, la fonction final sera exécutée.

Cela semble bien, le code est plus maintenable et plus beau, et si vous voulez la simultanéité ?

Copier le code Le code est le suivant :
​ q.all([promise0, promise1, promise2]).spread(function(val0, val1, val2){
console.log(arguments);
                    }).then(function(){
console.log("done");
                  }).catch(function(err){
console.log(err);
                });

Q fournit également une API pour la concurrence. Appelez la méthode all et transmettez un tableau Promise pour continuer à utiliser le style de chaîne de then. Il existe également des éléments comme q.nfbind qui peuvent convertir l'API native de Node.js en Promise pour unifier le format de code, ce qui est également très bien. D'autres API ne seront pas décrites en détail ici.

Conclusion

Cet article présente principalement l'utilisation de Promise pour résoudre les problèmes de flux de contrôle Node.js, mais Promise peut également être appliqué au front-end. EMCAScript6 a fourni une prise en charge native de l'API. Il convient de souligner que Promise n'est pas la seule solution. Async est également un bon choix et fournit une API de contrôle de concurrence plus conviviale. Cependant, je pense que Promise présente plus d'avantages lors de l'encapsulation de fonctions avec des méthodes asynchrones.

D'accord, cet article se termine ici, j'espère qu'il pourra être utile à tout le monde.

Étiquettes associées:
source:php.cn
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal