web-dev-qa-db-fra.com

Corrigez Essayez ... Syntaxe de capture en utilisant Async/Await

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 awaiting à 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?

28
freedomflyer

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 catchtoutes 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

    • assigner une valeur par défaut à la variable dans le bloc catch
    • return early ou re -throw une exception au bloc catch
    • définir un indicateur pour savoir si le bloc catch a intercepté une exception et le tester dans une condition if
    • vérifier si la valeur de la variable a été attribuée

    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 returns précoces à partir de la fonction externe.

22
Bergi

Une autre approche plus simple consiste à ajouter .catch à la fonction promesse. ex:

const createdUser = await this.User.create(userInfo).catch( error => {
// handle error
})
0
nevf