web-dev-qa-db-fra.com

Comprendre les promesses dans Node.js

D'après ce que j'ai compris, il existe trois façons d'appeler du code asynchrone:

  1. Événements, par exemple request.on("event", callback);
  2. Rappels, par exemple fs.open(path, flags, mode, callback);
  3. Promesses

J'ai trouvé la bibliothèque de promesses de nœuds mais je ne la comprends pas.

Quelqu'un pourrait-il expliquer en quoi consistent les promesses et pourquoi je devrais les utiliser?

Aussi, pourquoi a-t-il été supprimé de Node.js?

146
ajsie

Promises dans node.js a promis de faire un peu de travail, puis d’avoir des rappels distincts à exécuter en cas de succès et d’échec, ainsi que de gérer les délais. Une autre façon de penser aux promesses dans node.js était qu’il s’agissait d’émetteurs ne pouvant émettre que deux événements: succès et erreur.

La bonne chose à propos des promesses est que vous pouvez les combiner dans des chaînes de dépendance (ne faites Promise C que lorsque Promise A et Promise B complète).

En les retirant du fichier node.js principal, il a été possible de construire des modules avec différentes implémentations de promesses pouvant s’asseoir sur le noyau. Certains d'entre eux sont node-promise et futures .

90
Paul Robinson

Comme cette question a encore de nombreux points de vue (comme le mien), je voulais souligner que:

  1. node-promise me semble plutôt mort (le dernier commit remonte à environ un an) et ne contient pratiquement aucun test.
  2. Le module Futurs me semble très gonflé et est mal documenté (et je pense que les conventions de dénomination sont tout simplement mauvaises)
  3. La meilleure façon de procéder semble être le q framework , actif et bien documenté.
98
enyo

Une promesse est une "chose" qui représente les résultats "éventuels" d'une opération pour ainsi dire. Le point à noter ici est que, il résume les détails de lorsque quelque chose se passe et vous permet de vous concentrer sur ce qui devrait se passer après que quelque chose se passe. Cela se traduira par un code propre et maintenable. Au lieu d'avoir un rappel dans un rappel, votre code ressemblera à ceci:

 var request = new Promise(function(resolve, reject) {
   //do an ajax call here. or a database request or whatever.
   //depending on its results, either call resolve(value) or reject(error)
   //where value is the thing which the operation's successful execution returns and
   //error is the thing which the operation's failure returns.
 });

 request.then(function successHandler(result) {
   //do something with the result
 }, function failureHandler(error) {
  //handle
 });

La spécification des promesses stipule qu'une promesse

then

la méthode devrait renvoyer une nouvelle promesse qui est remplie lorsque le successHandler ou le rappel failHandler donné est terminé. Cela signifie que vous pouvez enchaîner des promesses lorsque vous avez un ensemble de tâches asynchrones à exécuter et être assuré que le séquencement des opérations est garanti exactement comme si vous aviez utilisé des rappels. Ainsi, au lieu de passer un rappel dans un rappel, le code avec les promesses chaînées ressemble à ceci:

var doStuff = firstAsyncFunction(url) {
                return new Promise(function(resolve, reject) {
                       $.ajax({
                        url: url,
                        success: function(data) {
                            resolve(data);
                        },
                        error: function(err) {
                             reject(err); 
                        } 
                  });
               };
doStuff
  .then(secondAsyncFunction) //returns a promise
  .then(thirdAsyncFunction); //returns a promise

Pour en savoir plus sur les promesses et pourquoi elles sont super cool, consultez le blog de Domenic: http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/

19
Hrishi

Ce nouveau tutoriel sur les promesses de l'auteur de PouchDB est probablement le meilleur que j'ai jamais vu. Il couvre judicieusement les erreurs classiques des recrues en vous montrant les modèles d'utilisation corrects et même quelques anti-modèles qui sont encore couramment utilisés - même dans d'autres tutoriels !!

Prendre plaisir!

PS Je n’ai pas répondu à d’autres parties de cette question car elles ont été bien couvertes par d’autres.

12
Tony O'Hagan

Mike Taulty possède une série de vidéos , chacune d’une durée inférieure à 10 minutes, décrivant le fonctionnement de la bibliothèque WinJS Promise.

Ces vidéos sont assez instructives et Mike réussit à montrer la puissance de l'API Promise avec quelques exemples de code bien choisis.

var twitterUrl = "http://search.Twitter.com/search.json?q=windows";
var promise = WinJS.xhr({ url: twitterUrl });

 promise = promise.then(
     function (xhr) {
     },
     function (xhr) {
         // handle error
     });

Le traitement de la manière dont les exceptions sont traitées est particulièrement bon.

Malgré les références de WinJs, il s'agit d'une série de vidéos d'intérêt général, car l'API Promise est globalement similaire à travers ses nombreuses implémentations.

RSVP est une implémentation Promise légère qui passe avec succès la suite de tests Promise/A +. J'aime assez l'API, car son style est similaire à celui de l'interface WinJS.

Mise à jour avril 2014

Incidemment, la bibliothèque WinJS est maintenant open source .

7
Noel Abrahams

Un autre avantage des promesses est que la gestion des erreurs et le lancement et la récupération des exceptions sont bien meilleurs que d'essayer de gérer cela avec des rappels.

La bibliothèque bluebird implémente les promesses et vous donne de superbes traces de pile, est très rapide et vous avertit des erreurs inexploitées. Il est également plus rapide et utilise moins de mémoire que les autres bibliothèques de promesses, selon http://bluebirdjs.com/docs/benchmarks.html

5
llambda

Qu'est-ce qu'une promesse?

Une promesse est simplement un objet qui représente le résultat d'une opération asynchrone. Une promesse peut être dans l’un des 3 états suivants:

en attente :: Ceci est l'état initial, signifie que la promesse n'est ni remplie ni rejetée.

rempli :: Cela signifie que la promesse a été remplie, signifie que la valeur représentée par la promesse est prête à être utilisée.

rejeté :: Cela signifie que les opérations ont échoué et ne peuvent donc pas tenir la promesse. Outre les États, il existe trois entités importantes associées aux promesses que nous devons vraiment comprendre.

  1. executor function :: executor function définit l'opération asynchrone à exécuter et dont le résultat est représenté par la promesse. Il commence l'exécution dès que l'objet de promesse est initialisé.

  2. resolve :: resol est un paramètre transmis à la fonction exécuteur, et si l'exécuteur s'exécute avec succès, cette résolution s'appelle transmettre le résultat.

  3. rejeter :: rejeter est un autre paramètre transmis à la fonction exécuteur, et il est utilisé lorsque la fonction exécuteur échoue. Le motif d'échec peut être transmis au rejet.

Ainsi, chaque fois que nous créons un objet de promesse, nous devons fournir un exécuteur, une résolution et un rejet.

Référence :: Promises

4
Rishabh.IO

J'ai également étudié les promesses dans node.js récemment. À ce jour, le when.js semble être la solution en raison de sa rapidité et de son utilisation des ressources, mais la documentation sur q.js m'a permis de mieux comprendre. Utilisez donc when.js mais la documentation q.js pour comprendre le sujet.

Depuis le q.js readme sur github:

Si une fonction ne peut pas renvoyer de valeur ou lever une exception sans bloquer, elle peut renvoyer une promesse. Une promesse est un objet qui représente la valeur de retour ou l'exception levée que la fonction peut éventuellement fournir. Une promesse peut également être utilisée en tant que proxy pour un objet distant afin de surmonter la latence.

0
Andrew Roberts