J'ai lu plusieurs articles sur ce sujet, mais il n'est toujours pas clair pour moi s'il y a une différence entre Promise.reject
vs et lancer une erreur. Par exemple,
Utilisation de Promise.reject
return asyncIsPermitted()
.then(function(result) {
if (result === true) {
return true;
}
else {
return Promise.reject(new PermissionDenied());
}
});
Utilisation de lancer
return asyncIsPermitted()
.then(function(result) {
if (result === true) {
return true;
}
else {
throw new PermissionDenied();
}
});
Ma préférence est d'utiliser throw
simplement parce qu'il est plus court, mais je me demandais s'il y avait un avantage l'un par rapport à l'autre.
javascript
promise
Naresh
la source
la source
.then()
gestionnaire intercepte l'exception levée et la transforme automatiquement en promesse rejetée. Depuis que j'ai lu que les exceptions levées ne sont pas particulièrement rapides à exécuter, je suppose que le retour de la promesse rejetée pourrait être légèrement plus rapide à exécuter, mais vous auriez à concevoir un test dans plusieurs navigateurs modernes si cela était important à savoir. J'utilise personnellementthrow
car j'aime la lisibilité.throw
est qu'il ne résulterait pas en une promesse rejetée s'il était lancé à partir d'un rappel asynchrone, tel qu'un setTimeout. jsfiddle.net/m07van33 @Blondie votre réponse était correcte.reject
de ma liste de paramètres.Réponses:
Il n'y a aucun avantage à utiliser l'un contre l'autre, mais il y a un cas spécifique où
throw
cela ne fonctionnera pas. Cependant, ces cas peuvent être résolus.Chaque fois que vous êtes dans un rappel de promesse, vous pouvez l'utiliser
throw
. Cependant, si vous êtes dans un autre rappel asynchrone, vous devez utiliserreject
.Par exemple, cela ne déclenchera pas le catch:
Au lieu de cela, vous vous retrouvez avec une promesse non résolue et une exception non capturée. C'est un cas où vous voudriez utiliser à la place
reject
. Cependant, vous pouvez résoudre ce problème de deux manières.la source
throw error
, vous ne pouvez pas non plus utiliserreturn Promise.reject(err)
ce que l'OP nous demandait de comparer. C'est essentiellement pourquoi vous ne devriez pas mettre de rappels asynchrones dans les promesses. Promettez tout ce qui est asynchrone et vous n'aurez plus ces restrictions.Array#forEach
) et avec ceux-ci, lancer à l'intérieur fonctionnerait.throw
cela ne fonctionnera pas etPromise.reject
est plutôt un meilleur choix. Cependant, les extraits ne sont pas affectés par l'un de ces deux choix et donnent le même résultat indépendamment de ce que vous choisissez. Suis-je en train de manquer quelque chose?reject
qui a été transmis aunew Promise(fn)
rappel.return Promise.reject()
etthrow
. Il ne mentionne pas lereject
rappel donné dans lanew Promise(function(resolve, reject))
construction. Ainsi, alors que vos deux extraits montrent à juste titre quand vous devez utiliser le rappel de résolution, la question de OP n'était pas celle-là.Un autre fait important est que
reject()
NE met PAS fin au flux de contrôle comme le fait unereturn
instruction. En revanche,throw
met fin au flux de contrôle.Exemple:
contre
la source
return reject()
, afin que la ligne suivante ne s'exécute pas.return reject()
c'est simplement un raccourci pourreject(); return
dire ce que vous voulez, c'est mettre fin au flux. La valeur de retour de l' exécuteur (la fonction transmise ànew Promise
) n'est pas utilisée, c'est donc sans danger.Oui, la plus grande différence est que le rejet est une fonction de rappel qui est exécutée après le rejet de la promesse, alors que throw ne peut pas être utilisé de manière asynchrone. Si vous avez choisi d'utiliser le rejet, votre code continuera à s'exécuter normalement de manière asynchrone tandis que throw donnera la priorité à l'achèvement de la fonction résolveur (cette fonction s'exécutera immédiatement).
Un exemple que j'ai vu qui m'a aidé à clarifier le problème est que vous pouvez définir une fonction de délai d'attente avec rejet, par exemple:
Ce qui précède ne serait pas possible d'écrire avec throw.
Dans votre petit exemple, la différence est indiscernable, mais lorsqu'il s'agit d'un concept asynchrone plus compliqué, la différence entre les deux peut être drastique.
la source
TLDR: Une fonction est difficile à utiliser lorsqu'elle renvoie parfois une promesse et lève parfois une exception. Lors de l'écriture d'une fonction asynchrone, préférez signaler un échec en renvoyant une promesse rejetée
Votre exemple particulier obscurcit certaines distinctions importantes entre eux:
Étant donné que vous gérez des erreurs dans une chaîne de promesses, les exceptions levées sont automatiquement converties en promesses rejetées. Cela peut expliquer pourquoi ils semblent être interchangeables - ils ne le sont pas.
Considérez la situation ci-dessous:
Ce serait un anti-modèle car vous auriez alors besoin de prendre en charge les cas d'erreurs asynchrones et de synchronisation. Cela pourrait ressembler à:
Pas bon et c'est exactement là où
Promise.reject
(disponible dans la portée mondiale) vient à la rescousse et se différencie efficacementthrow
. Le refactoriste devient désormais:Cela vous permet désormais d'en utiliser un seul
catch()
pour les pannes de réseau et le contrôle d'erreur synchrone pour le manque de jetons:la source
Promise.reject
outhrow
quand vous voulez retourner une promesse rejetée (une promesse qui passera à la suivante.catch()
).checkCredentials(x).then(onFulfilled).catch(e) {}
et avoir lacatch
poignée à la fois le cas de rejet et le cas d'erreur levée?Un exemple à essayer. Remplacez simplement isVersionThrow par false pour utiliser le rejet au lieu du lancer.
la source