Oui, les Promesses sont des rappels asynchrones. Ils ne peuvent rien faire que les rappels ne peut pas le faire, et vous rencontrent les mêmes problèmes avec l'asynchronie comme de simples rappels.
Cependant, les Promesses sont plus que juste des rappels. Ils sont d'une très puissant de l'abstraction, de permettre à plus propre et mieux, code fonctionnel avec moins de risques d'erreurs standard.
Alors, quelle est l'idée principale?
Les promesses sont des objets représentant le résultat d'une seule personne (asynchrone) le calcul. Ils résoudre à ce résultat qu'une seule fois. Il y a quelques choses ce que cela signifie:
Promet de mettre en œuvre un modèle observateur:
- Vous n'avez pas besoin de connaître les rappels qui va utiliser la valeur avant la fin de la tâche.
- Au lieu d'attendre les rappels comme les arguments de vos fonctions, vous pouvez facilement
return
une Promesse objet
- La promesse de stocker la valeur, et vous pouvez de manière transparente ajouter un rappel à chaque fois que vous le souhaitez. Il sera appelée lorsque le résultat est disponible. "La transparence" signifie que lorsque vous avez une promesse et d'ajouter un rappel, il n'est pas de faire une différence dans votre code si le résultat a encore arrivé - l'API et les contrats sont les mêmes, la simplification de la mise en cache/memoisation beaucoup.
- Vous pouvez ajouter plusieurs rappels facilement
Les promesses sont chainable (monadique, si vous voulez):
- Si vous avez besoin pour transformer la valeur d'une promesse représente, vous carte une fonction de transformation sur la promesse et de revenir une nouvelle promesse que représente la transformée de résultat. Vous ne pouvez pas synchrone obtenir la valeur de l'utiliser d'une certaine façon, mais vous pouvez facilement soulever la transformation dans la promesse contexte. Pas de passe-partout pour les rappels.
- Si vous voulez à la chaîne de deux tâches asynchrones, vous pouvez utiliser l'
.then()
méthode. Il faudra un callback appelée avec le premier résultat, et retourne une promesse pour la suite de la promesse que le callback retourne.
Cela vous semble compliqué? Temps pour un exemple de code.
var p1 = api1(); // returning a promise
var p3 = p1.then(function(api1Result) {
var p2 = api2(); // returning a promise
return p2; // The result of p2 …
}); // … becomes the result of p3
// So it does not make a difference whether you write
api1().then(function(api1Result) {
return api2().then(console.log)
})
// or the flattened version
api1().then(function(api1Result) {
return api2();
}).then(console.log)
L'aplatissement ne vient pas par magie, mais vous pouvez le faire facilement. Pour votre fortement imbriqués exemple, la quasi-équivalente
api1().then(api2).then(api3).then(/* do-work-callback */);
Si le fait de voir le code de ces méthodes permet de comprendre, d' ici la une promesse lib en quelques lignes.
Quel est le grand tapage au sujet des promesses?
La Promesse d'abstraction permet de beaucoup mieux la composabilité des fonctions. Par exemple, à côté d' then
de l'enchaînement, l' all
fonction crée une promesse pour le résultat combiné de plusieurs parallèle d'attente de promesses.
Dernière mais pas moins Promet viennent avec système intégré de gestion des erreurs. Le résultat du calcul peut être que la promesse est rempli avec une valeur, ou s'il est rejeté avec raison. Toutes la composition des fonctions de gérer cela automatiquement et propager les erreurs dans la promesse de chaînes, de sorte que vous n'avez pas besoin de s'en soucier explicitement partout - contrairement à la plaine-rappel de la mise en œuvre. En fin de compte, vous pouvez ajouter un dédié erreur de rappel pour tous produits d'exceptions.
Pour ne pas mentionner avoir à convertir des choses de promesses.
C'est assez banal en fait avec une bonne promesse de bibliothèques, de voir Comment puis-je convertir un rappel de l'API de promesses?