451 votes

Comment rejeter en syntaxe async / wait?

Comment puis-je rejeter une promesse renvoyée par une fonction async / wait?

par exemple à l'origine

 foo(id: string): Promise<A> {
  return new Promise((resolve, reject) => {
    someAsyncPromise().then((value)=>resolve(200)).catch((err)=>reject(400))
  });
}
 

Traduire en asynchrone / wait

 async foo(id: string): Promise<A> {
  try{
    await someAsyncPromise();
    return 200;
  } catch(error) {//here goes if someAsyncPromise() rejected}
    return 400; //this will result in a resolved promise.
  });
}
 

Alors, comment pourrais-je bien rejeter cette promesse dans ce cas?

494voto

T.J. Crowder Points 285826

Votre meilleur pari est de throw un Error habillage de la valeur, ce qui entraîne le refus de la promesse avec un Error habillage de la valeur:

} catch (error) {
    throw new Error(400);
}

Vous pouvez aussi throw la valeur, mais alors il n'y a aucune trace de la pile d'information:

} catch (error) {
    throw 400;
}

Alternativement, retour le refus de la promesse avec un Error habillage de la valeur:

} catch (error) {
    return Promise.reject(new Error(400));
}

(Ou juste return Promise.reject(400);, mais encore une fois, alors il n'y a pas d'informations de contexte.)

(Dans votre cas, que vous êtes en utilisant TypeScript et foos'retrn valeur est Promise<A>, vous devez utiliser return Promise.reject<A>(400 /*or error*/);)

Dans un async/await situation, cette dernière est sans doute un peu de sémantique mis-match, mais il fonctionne.

Si vous jetez un Error, qui joue bien avec tout en consommant votre foos'entraîner avec await syntaxe:

try {
    await foo();
} catch (error) {
    // Here, `error` would be an `Error` (with stack trace, etc.).
    // Whereas if you used `throw 400`, it would just be `400`.
}

199voto

David Points 4696

Il convient également de mentionner que vous pouvez simplement chaîner une fonction catch() après l’appel de votre opération asynchrone, car une garantie est toujours retournée sous le capot.

 await foo().catch(error => console.log(error));
 

De cette façon, vous pouvez éviter la syntaxe try/catch si vous ne l'aimez pas.

16voto

Vous pouvez créer une fonction wrapper qui prend une promesse et retourne un tableau avec les données si aucune erreur et l'erreur s'il y a eu une erreur.

 function safePromise(promise) {
  return promise.then(data => [ data ]).catch(error => [ null, error ]);
}
 

Utilisez-le comme ceci dans ES7 et dans une fonction asynchrone :

 async function checkItem() {
  const [ item, error ] = await safePromise(getItem(id));
  if (error) { return null; } // handle error and return
  return item; // no error so safe to use item
}
 

12voto

OzzyTheGiant Points 309

Une meilleure façon d'écrire la fonction async serait en retournant une attente de la Promesse de le démarrer, puis manipuler à la fois des rejets et des résolutions dans le rappel de la promesse, plutôt que de simplement cracher le refus de la promesse de l'erreur. Exemple:

async foo(id: string): Promise<A> {
    return new Promise(function(resolve, reject) {
        // execute some code here
        if (success) { // let's say this is a boolean value from line above
            return resolve(success);
        } else {
            return reject(error); // this can be anything, preferably an Error object to catch the stacktrace from this function
        }
    });
}

Alors que vous venez de la chaîne d'méthodes, sur le formulaire de promesse:

async function bar () {
    try {
        var result = await foo("someID")
        // use the result here
    } catch (error) {
        // handle error here
    }
}

bar()

La Source de ce tutoriel:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

8voto

unional Points 4754

Ce n'est pas une réponse à celle de @TJ Crowder. Juste un commentaire qui répond au commentaire "Et en fait, si l'exception doit être convertie en rejet, je ne suis pas sûr de me préoccuper de savoir si c'est une erreur. Les raisons pour lesquelles je ne lance que l'erreur ne s'appliquent probablement pas. "

Si votre code utilise async / await , il est toujours recommandé de rejeter avec Error au lieu de 400 :

 try {
  await foo('a');
}
catch (e) {
  // you would still want `e` to be an `Error` instead of `400`
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X