Donc, en gros, vous demandez quelle est la différence entre ces deux (où p
est une promesse créée à partir d'un code précédent):
return p.then(...).catch(...);
et
return p.catch(...).then(...);
Il existe des différences lorsque p résout ou rejette, mais que ces différences comptent ou non dépend de ce que fait le code à l'intérieur des gestionnaires .then()
ou .catch()
.
Que se passe-t-il lorsque p
résout:
Dans le premier schéma, lors de la p
résolution, le .then()
gestionnaire est appelé. Si ce .then()
gestionnaire renvoie une valeur ou une autre promesse qui finit par se résoudre, alors le .catch()
gestionnaire est ignoré. Mais, si le .then()
gestionnaire lève ou retourne une promesse qui finalement rejette, alors le .catch()
gestionnaire exécutera à la fois un rejet dans la promesse d'origine p
, mais aussi une erreur qui se produit dans le .then()
gestionnaire.
Dans le second schéma, lors de la p
résolution, le .then()
gestionnaire est appelé. Si ce .then()
gestionnaire lève ou retourne une promesse qui finit par rejeter, alors le .catch()
gestionnaire ne peut pas l'attraper car c'est avant lui dans la chaîne.
Donc, c'est la différence n ° 1. Si le .catch()
gestionnaire est AFTER, il peut également intercepter des erreurs à l'intérieur du .then()
gestionnaire.
Que se passe-t-il en cas de p
rejet:
Maintenant, dans le premier schéma, si la promesse est p
rejetée, alors le .then()
gestionnaire est ignoré et le .catch()
gestionnaire sera appelé comme prévu. Ce que vous faites dans le .catch()
gestionnaire détermine ce qui est renvoyé comme résultat final. Si vous retournez simplement une valeur du .catch()
gestionnaire ou si vous retournez une promesse qui se résout finalement, la chaîne de promesse passe à l'état résolu car vous avez "géré" l'erreur et l'avez renvoyée normalement. Si vous lancez ou renvoyez une promesse rejetée dans le .catch()
gestionnaire, la promesse retournée reste rejetée.
Dans le second schéma, si la promesse est p
rejetée, le .catch()
gestionnaire est appelé. Si vous retournez une valeur normale ou une promesse qui se résout finalement à partir du .catch()
gestionnaire ("gérant" ainsi l'erreur), alors la chaîne de promesse passe à l'état résolu et le .then()
gestionnaire après le .catch()
sera appelé.
Voilà donc la différence n ° 2. Si le .catch()
gestionnaire est BEFORE, il peut gérer l'erreur et autoriser le .then()
gestionnaire à être appelé.
Quand utiliser lequel:
Utilisez le premier schéma si vous ne voulez qu'un seul .catch()
gestionnaire qui puisse intercepter les erreurs dans la promesse d'origine p
ou dans le .then()
gestionnaire et un rejet de p
devrait ignorer le .then()
gestionnaire.
Utilisez le deuxième schéma si vous voulez être en mesure de détecter les erreurs dans la promesse d'origine p
et peut-être (selon les conditions), permettre à la chaîne de promesse de continuer comme résolue, exécutant ainsi le .then()
gestionnaire.
L'autre option
Il existe une autre option pour utiliser les deux rappels auxquels vous pouvez passer .then()
comme dans:
p.then(fn1, fn2)
Cela garantit qu'un seul fn1
ou fn2
sera appelé. Si p
résout, alors fn1
sera appelé. Si p
rejette, alors fn2
sera appelé. Aucun changement de résultat fn1
ne peut jamais faire fn2
être appelé ou vice versa. Donc, si vous voulez être absolument sûr qu'un seul de vos deux gestionnaires est appelé indépendamment de ce qui se passe dans les gestionnaires eux-mêmes, vous pouvez utiliser p.then(fn1, fn2)
.