J'aime la planéité de la nouvelle fonctionnalité Async/Await
disponible dans TypeScript, etc. Cependant, je ne suis pas sûr d'aimer le fait de devoir déclarer la variable await
ing à l'extérieur d'un bloc try...catch
pour pouvoir l'utiliser plus tard. . Ainsi:
let createdUser
try {
createdUser = await this.User.create(userInfo)
} catch (error) {
console.error(error)
}
console.log(createdUser)
// business
// logic
// goes
// here
Corrigez-moi si je me trompe, mais cela semble être la meilleure pratique pas de placer plusieurs lignes de logique métier dans le corps de try
, de sorte que je ne reste plus qu’à déclarer createdUser
en dehors du bloc, en lui affectant dans le bloc, puis l’utiliser après.
Quelle est la meilleure pratique dans ce cas?
Il semble que la meilleure pratique consiste à ne pas placer plusieurs lignes de logique métier dans le corps d'essai.
En fait, je dirais que ça l'est. Vous souhaitez généralement que catch
toutes les exceptions ne fonctionne pas avec la valeur:
try {
const createdUser = await this.User.create(userInfo);
console.log(createdUser)
// business logic goes here
} catch (error) {
console.error(error) // from creation or business logic
}
Si vous voulez détecter et gérer les erreurs uniquement à partir de la promesse, vous avez trois choix:
Déclarez la variable extérieur et branchez selon qu'il y ait eu une exception ou non. Cela peut prendre diverses formes, comme
catch
return
early ou re -throw
une exception au bloc catch
catch
a intercepté une exception et le tester dans une condition if
let createdUser; // or use `var` inside the block
try {
createdUser = await this.User.create(userInfo);
} catch (error) {
console.error(error) // from creation
}
if (createdUser) { // user was successfully created
console.log(createdUser)
// business logic goes here
}
Testez l’exception interceptée pour son type, puis gérez-la ou consultez-la à nouveau.
try {
const createdUser = await this.User.create(userInfo);
// user was successfully created
console.log(createdUser)
// business logic goes here
} catch (error) {
if (error instanceof CreationError) {
console.error(error) // from creation
} else {
throw error;
}
}
Malheureusement, JavaScript standard (encore) ne prend pas en charge la syntaxe pour les exceptions conditionnelles .
Utilisez then
avec deux rappels au lieu de try
/catch
. C’est vraiment la manière la moins laide et ma recommandation personnelle tient également à sa simplicité et à son exactitude. Ne comptez pas sur les erreurs marquées ni sur l’aspect de la valeur du résultat pour faire la distinction entre réalisation et rejet de la promesse:
await this.User.create(userInfo).then(createdUser => {
// user was successfully created
console.log(createdUser)
// business logic goes here
}, error => {
console.error(error) // from creation
});
Bien sûr, cela présente l’inconvénient d’introduire des fonctions de rappel, ce qui signifie que vous ne pouvez pas faire aussi facilement une boucle break
/continue
ou faire des return
s précoces à partir de la fonction externe.
Une autre approche plus simple consiste à ajouter .catch à la fonction promesse. ex:
const createdUser = await this.User.create(userInfo).catch( error => {
// handle error
})