web-dev-qa-db-fra.com

Bluebird, promesses et puis ()

Je n'utilise bluebird que depuis quelques jours mais je veux revoir tout mon ancien code et promisify it :)

Mon problème est que je ne saisis toujours pas complètement le flux des commandes then().

Considérez ces deux blocs:

UNE

methodThatReturnsAPromise().then(task2).then(task3);

B

var promise = methodThatReturnsAPromise();
promise.then(task2)
promise.then(task3);
  1. dans le scénario A task3 obtiendra le résultat de task2? En B, ils obtiennent tous le résultat de la première promesse?

  2. En quoi le second diffère-t-il de l'exécution de Promise.all de Bluebird?

  3. Comment ces A/B/Promise.all diffèrent quand il s'agit d'utiliser la méthode catch (où dois-je le mettre).

Désolé, c'est un tas de questions en une.

40
Madd0g

Bienvenue dans le monde merveilleux des promesses.

Comment then fonctionne dans votre exemple

Votre affirmation dans 1 est correct. Nous pouvons simuler une promesse se résolvant dans Bluebird en utilisant Promise.resolve sur une valeur.

Montrons ceci:

Obtenons une fonction qui renvoie une promesse:

function foo(){
    return Promise.resolve("Value");    
}

foo().then(alert);

Ce court extrait avertira "Value" as on peut voir .

Maintenant, créons deux promesses supplémentaires, chacune qui alerte et renvoie des valeurs différentes.

function task2(e){
    alert("In two got " + e);
    return " Two ";
}
function task3(e){
    alert("In three got " + e);
    return " Three ";
}

Ainsi, comme vous pouvez le voir dans votre premier code il se résoudra en effet en chaîne, chacun avec la valeur de la partie précédente.

Dans le deuxième exemple, task2 et task3 obtiendront la même valeur et s'exécuteront également ensemble (c'est-à-dire que la tâche 3 n'attendra pas la tâche 2). Vous pouvez voir que ici .

Promise.all

Promise.all (ou simplement renvoyer un tableau à partir d'un gestionnaire d'accomplissement then puis utiliser .spread) est utilisé pour attendre la fin de plusieurs résultats. Sur votre exemple, vous vous accrochez à un seul résultat en plusieurs parties.

La prise

Vous placez toujours catch où vous voulez que l'erreur soit capturée. Comme vous le feriez normalement en code synchrone. N'oubliez pas de toujours lancer une promesse ou du code promis.

48
Benjamin Gruenbaum

dans le scénario A task3 obtiendra le résultat de task2? En B, ils obtiennent tous le résultat de la première promesse?

Oui.

En quoi le second diffère-t-il de l'exécution de Promise.all à partir de bluebird?

Vous ne récupérez pas les résultats des tâches (parallèles) 2 et 3 dans une nouvelle promesse.

Comment ces A/B/Promise.all diffèrent-ils quand il s'agit d'utiliser la méthode catch (où dois-je le mettre).

Habituellement, vous le mettriez à la fin de la chaîne, sauf que vous voulez attraper une erreur spécifique.

promise.catch()
// handles rejections of this promise

promise.then(task2).catch()
// handles rejections from either promise or task2
// if promise is rejected, task2 will not be executed

Promise.all(promise.then(task2), promise.then(task3)).catch()
// handles rejections from any.
// if promise is rejected, neither task2 nor task3 will be executed
// if task2 or task3 throw, the error will immediately handled
// and the other task will not be affected (but its result is unavailable)
12
Bergi

Vous n'obtenez pas un principe simple chaînage

En premier on peut s'écrire comme

var promise   = methodThatReturnsAPromise(),
    promise1  = promise.then(task2);
promise1.then(task3);

Dans le deuxième cas

var promise   = methodThatReturnsAPromise();
promise.then(task2)
promise.then(task3);

J'espère que cela explique la différence entre les deux

3
aWebDeveloper