Je travaille sur une application Angular 6 et on m'a dit que ce qui suit est un anti-modèle:

await someFunction().then(result => {
    console.log(result);
});

Je me rends compte qu'il est inutile d'attendre une chaîne de promesses. Si someFunction () renvoie une promesse, vous n'avez pas besoin d'une chaîne de promesses si vous l'attendez. Tu peux le faire:

const result = await someFunction();
console.log(result);

Mais on me dit qu'attendre une chaîne de promesses peut provoquer des bugs, ou qu'elle va casser des choses dans mon code. Si le premier extrait de code ci-dessus fait la même chose que le deuxième extrait, qu'importe celui qui est utilisé. Quels dangers le premier extrait de code présente-t-il que le second ne fait pas?

9
Gibran Shah 27 janv. 2019 à 09:37

3 réponses

Meilleure réponse

Sous le capot, asynchroniser / attendre n'est que des promesses.

Autrement dit, lorsque vous avez du code qui ressemble à:

const result = await myAsyncFunction();   
console.log(result): 

C'est exactement la même chose que d'écrire:

myAsyncFunction().then(data => {
   const result = data; 
   console.log(result); 
}); 

La raison alors - que vous ne devriez pas mélanger les chaînes asynchrone / wait et .then - est parce que c'est déroutant.

Il vaut mieux choisir un seul style et s'y tenir.

Et pendant que vous en choisissez un - vous pourriez aussi bien choisir async / wait - c'est plus compréhensible.

3
dwjohnston 27 janv. 2019 à 06:50

On me dit qu'attendre une chaîne de promesses va casser des choses dans mon code.

Pas nécessairement, vos deux extraits de code fonctionnent en effet de la même manière (tant que someFunction() renvoie vraiment une promesse).

Qu'importe lequel est utilisé. Quels dangers le premier extrait de code présente-t-il que le second ne fait pas?

C'est plus difficile à comprendre et à maintenir, c'est déroutant de mélanger différents styles. La confusion conduit à des bugs.

Considérez que vous auriez besoin d'ajouter un autre appel de promesse à l'emplacement de l'appel console.log(), ou même un retour conditionnel de la fonction. Pouvez-vous utiliser await dans le rappel comme ailleurs dans la fonction, avez-vous besoin de return le résultat du rappel then, est-il même possible de return de l'extérieur fonction? Toutes ces questions n'apparaissent même pas dans le premier extrait. Et bien qu'ils puissent être facilement répondus pour votre exemple de jouet, il pourrait ne pas être aussi facile dans le code réel avec un flux de contrôle plus complexe et imbriqué.

Vous devriez donc préférer le plus concis et le plus propre. Respectez await pour cohérence , évitez then dans async function s 1 .

1: Bien sûr, il y a toujours une exception à la règle. Je dirais qu'il est plus propre d'utiliser le chaînage des promesses pour la gestion des erreurs dans certains cas où vous utiliseriez catch ou le deuxième then rappel.

5
Bergi 27 janv. 2019 à 16:13

Si votre code then renvoyait une promesse au lieu d'appeler console.log, votre premier exemple serait await, mais pas votre deuxième exemple.

Lorsque vous utilisez async/await, vous interceptez vos rejets dans des blocs try/catch. Votre code sera moins imbriqué et plus clair.

L'utilisation de then entraîne souvent une imbrication plus importante et une lecture du code plus difficile.

Vous pouvez await n'importe quoi, qu'il renvoie ou non un promise. Parfois, cela résiste à l'avenir en appelant une méthode qui peut un jour devenir asynchrone ou simplement renvoyer une promesse sans déclarer async.

Les inconvénients sont la complexité, les performances et la compatibilité, tous pâles par rapport aux gains.

Je trouve que si vous comptez sur la valeur de retour d'une fonction après l'avoir appelée, et qu'elle est ou peut devenir asynchrone, décorez d'appeler vos fonctions avec await pour le plus grand plaisir de votre cœur, qu'elle soit ou non asynchrone actuelle ou renvoie une promesse .

-1
Bryan 15 mars 2019 à 17:07