J'écris une fonction JavaScript qui fait une demande HTTP et renvoie une promesse pour le résultat (mais cette question s'applique également à une implémentation basée sur le rappel).
Si je sais immédiatement que les arguments fournis pour la fonction sont invalides, la fonction par exemple: p> lancer code> de manière synchrone ou doit-elle renvoyer une promesse rejetée (ou, si vous préférez, appelez le rappel avec une erreur code> d'erreur p> < p> Quelle est l'importance de ce que la fonction async doit toujours em> se comporter de manière asynchrable, en particulier pour les conditions d'erreur? Est-ce correct à
lancer code> si vous savez que le programme n'est pas dans un état approprié pour l'opération ASYNC pour continuer? P>
5 Réponses :
En fin de compte, la décision de lancer de manière synchrone ou non est à vous, et vous trouverez probablement des personnes qui soutiennent de chaque côté. L'important est de documenter le comportement et de maintenir la cohérence dans le comportement.
Mon avis em> sur la question est que votre deuxième option - transmettre l'erreur dans le rappel - semble plus élégante. Sinon vous vous retrouvez avec du code qui ressemble à ceci: p> Le flux de contrôle ici est légèrement déroutant. P> Il semble que ce soit mieux d'avoir Un seul si / else si / else code> structure dans le rappel et renverser le
Essayez / attrapez p> p> p>
Quelle est l'importance de ce que la fonction async doit toujours se comporter de manière asynchratante, en particulier pour les conditions d'erreur? P> blockQuote>
est-ce correct de
lancer code> si vous savez que le programme n'est pas dans un état approprié pour l'opération ASYNC pour continuer? P> blockQuote>
Oui, je pense personnellement que c'est OK quand c'est une erreur très différente de tous les a fabriqués de manière asynchrone et doit être traitée séparément de toute façon. P>
Si certains ID utilisateur sont connus pour être invalides car ils ne sont pas numériques, et certains sont rejetés sur le serveur (par exemple parce qu'ils sont déjà pris), vous devez constamment faire un rappel (async!) pour les deux cas. Si les erreurs ASYNC ne proviennent que des problèmes de réseau, etc., vous pourriez les signaler différemment. P>
Vous pouvez toujours
lancer code> quand une erreur " inattendue em>" est. Si vous exigez des userids valides, vous pourriez lancer sur ceux invalides. Si vous souhaitez anticiper des personnes non valides et que l'appelant les gère, vous devez utiliser une route d'erreur «unifiée» qui serait la promesse de rappel / rejetée pour une fonction asynchrone. P>
et pour répéter @Timothy: vous devez toujours documenter le comportement et maintenir la cohérence dans le comportement. P>
Les API de rappel Idéalement, ne devraient pas lancer mais ils jetent parce qu'il est très difficile d'éviter depuis que vous devez essayer de prendre littéralement partout. N'oubliez pas que l'erreur de lancer explicitement par C'est ce que le code ressemblerait à ce que le code se comporte selon ces Idéaux: P> lancer code> n'est pas requise pour une fonction à lancer. Une autre chose qui ajoute à ceci est que le rappel de l'utilisateur peut facilement lancer également, par exemple appelant
json.parse code> sans essayer de prendre.
readFile("file.json").then(JSON.parse).then(function(val) {
console.log(val.success);
})
.catch(SyntaxError, function(e) {
console.error("invalid json in file");
})
.catch(function(e){
console.error("unable to read file")
})
Si ce Listerfile lance une exception, il ne sera pas attrapé par les fonctions de capture définies là-bas. Mais si le disque de lecture retourne une promesse, alors ça marche
C'est en grande partie une question d'opinion. Tout ce que vous faites, faites-le de manière cohérente et de le documenter clairement.
Une information objective que je peux vous donner est que cela faisait l'objet de nombreuses discussions dans la conception des fonctions code> async code> de JavaScript, qui Comme vous le savez peut-être implicitement retourner des promesses pour leur travail. Vous pouvez également savoir que la partie d'un TC39 a décidé à la fin que même les erreurs lancées dans la partie synchrone d'un p> async code> fonction avant le premier
attendre code> ou
retour code> est synchrone fort>; Il ne devient aussi asynchrone qu'au point IT
attendre code> s ou retours. p>
async code> La fonction devrait rejeter sa promesse plutôt que de soulever une erreur synchrone. Par exemple: p>
async function someAsyncStuff() {
return 21;
}
function example() {
console.log("synchronous part of function");
throw new Error("failed");
return someAsyncStuff().then(x => x * 2);
}
try {
console.log("before call");
example().catch(e => { console.log("asynchronous:", e.message); });
console.log("after call");
} catch (e) {
console.log("synchronous:", e.message);
}
Idéalement, vous auriez une architecture multicouche comme des contrôleurs, des services, etc. Si vous faites des validations dans des services, jetez immédiatement et avez un bloc de capture dans votre contrôleur pour saisir le format d'erreur et envoyer un code d'erreur HTTP approprié. De cette façon, vous pouvez centraliser toute la logique de manutention de mauvaise demande. Si vous gérez chaque cas, vous finirez par écrire plus de code. Mais c'est comme ça que je le ferais. Dépend de votre cas d'utilisation p>
Regardez également Pourquoi les exceptions sont-elles utilisées pour rejeter des promesses dans JS?