async function
et le mot clef await
sont des « sucres syntaxiques », c’est-à-dire qu’ils n’ajoutent pas de nouvelles fonctionnalités en soi au langage mais permettent de créer et d’utiliser des promesses avec un code plus intuitif et qui ressemble davantage à la syntaxe classique du JavaScript à laquelle nous sommes habitués.
Ces mots clefs sont apparus avec la version 2017 du JavaScript et sont très prisés et utilisés par les API modernes. Il est donc intéressant de comprendre comment les utiliser.
Le mot clef async
Nous allons pouvoir placer le mot clef async
devant une déclaration de fonction (ou une expression de fonction, ou encore une fonction fléchée) pour la transformer en fonction asynchrone.
Utiliser le mot clef async
devant une fonction va faire que la fonction en question va toujours retourner une promesse. Dans le cas où la fonction retourne explicitement une valeur qui n’est pas une promesse, alors cette valeur sera automatiquement enveloppée dans une promesse.
Les fonctions définies avec async
vont donc toujours retourner une promesse qui sera résolue avec la valeur renvoyée par la fonction asynchrone ou qui sera rompue s’il y a une exception non interceptée émise depuis la fonction asynchrone.
See the Pen
Cours JavaScript 12.3.1 by Pierre (@pierregiraud)
on CodePen.
Le mot clef await
Le mot clef await
est uniquement valide au sein de fonctions asynchrones définies avec async
.
Ce mot clef permet d’interrompre l’exécution d’une fonction asynchrone tant qu’une promesse n’est pas résolue ou rejetée. La fonction asynchrone reprend ensuite puis renvoie la valeur de résolution.
See the Pen
Cours JavaScript 12.3.2 by Pierre (@pierregiraud)
on CodePen.
Le mot clef await
permet de mettre en pause l’exécution du code tant qu’une promesse n’est pas consommée, puis retourne ensuite le résultat de la promesse. Cela ne consomme aucune ressource supplémentaire puisque le moteur peut effectuer d’autres tâches en attendant : exécuter d’autres scripts, gérer des événements, etc.
Au final, await
est une syntaxe alternative à then()
, plus facile à lire, à comprendre et à écrire.
Utiliser async et await pour réécrire nos promesses
Prenons immédiatement un exemple concret d’utilisation de async
et await
.
Dans la leçon précédente, nous avons utilisé les promesses pour télécharger plusieurs scripts à la suite. Notre code ressemblait à cela :
Modifions ce code en utilisant async
et await
. Pour cela, il va nous suffire de définir une fonction async
et de remplacer les then()
par des await
comme ceci :
Notre script fonctionne et ajoute les fichiers les uns à la suite des autres. Le problème ici est que nous n’avons aucune prise en charge des erreurs. Nous allons immédiatement remédier à cela.
La gestion des erreurs avec la syntaxe async / await
Si une promesse est résolue (opération effectuée avec succès), alors await promise
retourne le résultat. Dans le cas d’un rejet, une erreur va être lancée de la même manière que si on utilisait throw
.
Pour capturer une erreur lancée avec await
, on peut tout simplement utiliser une structure try…catch
classique.
See the Pen
Cours JavaScript 12.3.3 by Pierre (@pierregiraud)
on CodePen.
Async/ await et all()
On va tout à fait pouvoir utiliser la syntaxe async / await
avec la méthode all()
. Cela va nous permettre d’obtenir la liste des résultats liés à ensemble de promesses avec un code plus lisible.
A retenir – La syntaxe async / await
Les mots clefs async
et await
sont un sucre syntaxique ajouté au JavaScript pour nous permettre d’écrire du code asynchrone : ils n’ajoutent aucune fonctionnalité en soi mais fournissent une syntaxe plus intuitive et plus claire pour définir des fonctions asynchrones et utiliser des promesses.
Utiliser le mot clef async
devant une fonction force la fonction à retourner une promesse et nous permet d’utiliser await
dans celle-ci.
En utilisant le mot clef await
devant une promesse, on oblige le JavaScript à attendre que la promesse soit consommée. Si la promesse est résolue, le résultat est retourné. Si elle est rompue, une erreur (exception) est générée.
Utiliser async / await
permet ainsi d’écrire du code asynchrone qui ressemble dans sa structure à du code synchrone auquel nous sommes habitués et nous permet notamment de nous passer de then()
et de catch()
(qu’on va tout de même pouvoir utiliser si le besoin s’en ressent).