Je creuse dans la fonction async / await du nœud 7 et je continue de trébucher sur du code comme celui-ci
function getQuote() {
let quote = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
return quote;
}
async function main() {
try {
var quote = await getQuote();
console.log(quote);
} catch (error) {
console.error(error);
}
}
main();
Cela semble être la seule possibilité de résoudre / rejeter ou retourner / lancer avec async / await, cependant, la v8 n'optimise pas le code dans les blocs try / catch?!
Existe-t-il des alternatives?
node.js
async-await
ecmascript-2017
Patrick
la source
la source
Réponses:
Alternatives
Une alternative à ceci:
serait quelque chose comme ça, en utilisant explicitement les promesses:
ou quelque chose comme ça, en utilisant le style de passage continu:
Exemple original
Ce que fait votre code d'origine est de suspendre l'exécution et d'attendre que la promesse retournée soit
getQuote()
réglée. Il continue ensuite l'exécution et écrit la valeur renvoyée dansvar quote
, puis l'imprime si la promesse a été résolue, ou lève une exception et exécute le bloc catch qui imprime l'erreur si la promesse a été rejetée.Vous pouvez faire la même chose en utilisant l'API Promise directement comme dans le deuxième exemple.
Performance
Maintenant, pour la performance. Testons-le!
Je viens d'écrire ce code -
f1()
donne1
comme valeur de retour,f2()
jette1
comme exception:Appelons maintenant le même code des millions de fois, d'abord avec
f1()
:Et puis passons
f1()
àf2()
:Voici le résultat que j'ai obtenu pour
f1
:Voici ce que j'ai pour
f2
:Il semble que vous puissiez faire quelque chose comme 2 millions de lancers par seconde dans un processus à un seul thread. Si vous faites plus que cela, vous devrez peut-être vous en inquiéter.
Résumé
Je ne m'inquiéterais pas des choses comme ça dans Node. Si des choses comme ça sont beaucoup utilisées, elles seront finalement optimisées par les équipes V8 ou SpiderMonkey ou Chakra et tout le monde suivra - ce n'est pas comme si ce n'était pas optimisé en tant que principe, ce n'est tout simplement pas un problème.
Même s'il n'est pas optimisé, je dirais toujours que si vous maximisez votre processeur dans Node, vous devriez probablement écrire votre calcul numérique en C - c'est à cela que servent les addons natifs, entre autres choses. Ou peut-être que des choses comme node.native conviendraient mieux à ce travail que Node.js.
Je me demande quel serait un cas d'utilisation qui aurait besoin de tant d'exceptions. En général, lever une exception au lieu de renvoyer une valeur est, eh bien, une exception.
la source
try catch
et non de la levée d'une exception. Bien que les chiffres soient petits, c'est presque 10 fois plus lent selon vos tests, ce qui n'est pas anodin.Alternative similaire à la gestion des erreurs dans Golang
Comme async / await utilise des promesses sous le capot, vous pouvez écrire une petite fonction utilitaire comme celle-ci:
Ensuite, importez-le chaque fois que vous avez besoin de détecter des erreurs et encapsulez votre fonction asynchrone qui renvoie une promesse avec elle.
la source
Une alternative au bloc try-catch est await-to-js lib. Je l'utilise souvent. Par exemple:
Cette syntaxe est beaucoup plus propre par rapport à try-catch.
la source
Au lieu de déclarer une variable possible pour contenir une erreur en haut, vous pouvez faire
Bien que cela ne fonctionnera pas si quelque chose comme une erreur TypeError ou Reference est renvoyé. Vous pouvez vous assurer qu'il s'agit d'une erreur régulière avec
Ma préférence pour cela est de tout emballer dans un gros bloc try-catch où plusieurs promesses sont créées, ce qui peut rendre difficile la gestion de l'erreur spécifiquement à la promesse qui l'a créée. L'alternative étant plusieurs blocs try-catch que je trouve tout aussi encombrants
la source
Une alternative plus propre serait la suivante:
En raison du fait que chaque fonction asynchrone est techniquement une promesse
Vous pouvez ajouter des captures aux fonctions lors de leur appel avec wait
Pas besoin d'essayer catch, car toutes les erreurs de promesses sont gérées, et vous n'avez aucune erreur de code, vous pouvez l'omettre dans le parent !!
Disons que vous travaillez avec mongodb, s'il y a une erreur, vous préférerez peut-être la gérer dans la fonction qui l'appelle plutôt que de créer des wrappers ou d'utiliser des try catch.
la source
J'aimerais faire de cette façon :)
C'est similaire à la gestion des erreurs avec
co
la source
await
!catch
de cette façon, d'après mon expérience, est dangereux. Toute erreur lancée dans la pile entière sera interceptée, pas seulement une erreur de cette promesse (ce qui n'est probablement pas ce que vous voulez).Le deuxième argument d'une promesse est déjà un rappel de rejet / échec. Il est préférable et plus sûr de l'utiliser à la place.
Voici une ligne unique dactylographiée que j'ai écrite pour gérer cela:
la source