ASYNC / AWAIT
#1 Comment s'utilise async / await ?
Le mot réservé wait
se place devant une requête asynchrone qui retourne une promesse. await
permet d'attendre la résolution de la promesse. Si vous regardez l'exemple ci-dessous, les instructions await requeteAsynchrone()
vont être bloquées en attente du résultat comme si on faisait des requêtes synchrones. Attention, c'est bloquant, mais c'est bloquant à l'intérieur d'une fonction qui elle est asynchrone, car, elle est déclarée avec le async function
.
Ca c'est très important, car c'est ce qui évite que votre application soit bloquée.
En plus, await
permet de récupérer directement le résultat de la requête au moyen d'une simple affectation 😎. Donc, vous n'avez plus besoin d'utiliser de then
et de coder un callback à l'intérieur de manière à récupérer le résultat.
Dans la doc MDN on vous dit que await
doit être utilisé à l'intérieur d'une fonction qui a été déclarée avec le mot réservé async
placé devant le mot réservé function
. C'est pour les raisons que je viens de vous expliquer.
Maintenant, concernant la déclaration avec async
. On va prendre une console JavaScript et on va déclarer la fonction listeDeRequete
avec async
devant. On va remarquer les choses suivantes :
- Le constructeur n'est pas le même que celui des fonctions classiques. C'est le constructeur
AsyncFunction
. - Justement ce constructeur est dérivé de celui des fonctions classiques.
- Cependant, un
typeof
ne fait pas la différence et renvoie toujours la chaîne'function'
. - Cette fonction renvoie une promesse. Ca ne suffit pas pour en faire une fonction asynchrone ! Mais si on consulte la doc MDN, on voit qu'en ayant mis
async
devant et bien le moteur JavaScript nous a alloué une fonction qui va avoir le comportement d'une fonction asynchrone.
#2 Exemple d'utilisation d'async / await.
On va faire un exemple dans lequel async
/ await
vont nous aider à enchaîner des requêtes asynchrones dans des conditions particulières. Ces conditions, ce sont celles dont on a parlé dans le tuto sur les promesses. On est toujours dans la même problématique, à savoir que souvent dans une requête asynchrone, on a besoin d'en faire une deuxième et pour faire cette deuxième, on a besoin d'attendre le résultat de la première. Et ainsi de suite, la troisième peut avoir besoin d'attendre le résultat de la deuxième.
On avait vu que sans les promesses, on tombait dans l'enfer des callbacks avec un code très peu lisible.
On avait vu que par contre, avec les promesses, on pouvait chaîner les opérations asynchrones dans des then
. Des then
que l'on avait écrit les uns sous les autres de manière à avoir un code lisible.
Ci-dessous je vais repartir du début et je vais prendre un exemple où je vais me servir des promesses pour enchaîner des opérations asynchrones. Ensuite on regardera comment avec async
/ await
on peut encore apporter de la lisibilité à ces séquences de codes.
Dans le code ci-dessous, qu'est-ce qu'il y a ?
- Je commence par programmer la fonction
requeteAsynchrone
. C'est une fonction qui simule une opération asynchrone. C'est une opération que j'ai promessifié puisque c'est moi qui fais lereturn
d'un objet de constructeurPromise
, c'est moi qui écris l'exécuteur et enfin, c'est moi qui déclenche l'appel àresolve
. Je le fais, après un délai que je provoque en utilisantsetTimeout
. L'argumentnum
, on peut le voir comme le numéro de la requête. Et enfin le délai est calculé par rapport ànum
multiplier par1000
de manière à avoir un délai en millisecondes. - Ensuite, je code ma fonction
listeDeRequete()
. Dans cette fonction, je vais faire ma séquence d'entrée / sortie asynchrone. Là, je commence par lancer l'opération asynchrone numéro une. Pour ça j'appellerequeteAsynchrone(1)
et je traite le résultat dans lethen
qui est collé derrière. Dans cethen
, je vais enchaîner une deuxième opération asynchrone en appelantrequeteAsynchrone(res_1+1)
après avoir obtenu le résultat derequeteAsynchrone(1)
. Je me sers de ce résultat pour simulation. Le résultatres_1+1
vaudra2
. - Ensuite, je continue de la même manière avec les opérations qui suivent.
- J'obtiens un code que l'on avait qualifié de lisible lorsque l'on avait fait les promesses et on s'en était félicité.
Ci-dessous, je constate que la fonction listeDeRequete()
est asynchrone en ce sens qu'elle ne contient que des opérations asynchrones. On peut vérifier que le console.log("Fin")
s'exécute avant les requêtes de la fonction.
Ci-dessous, je fais un console.log('Bonjour')
manuellement pour vérifier que mon application n'est pas bloquée.
Maintenant, il s'agit d'utiliser async
/ await
de manière à améliorer encore ce code.
J'utilise des structures syntaxiques await requeteAsynchrone(1)
, grosso modo à la place des then
. Je place le async
dans la déclaration de listeDeRequête
. Par contre, il ne faut pas oublier de mettre un try catch
pour récupérer deux choses en fait :
- Récupérer les promesses rompues qui pourraient être retournées par les appels à
requeteAsynchrone()
. - Récupérer les éventuelles exceptions qui pourraient être déclenchées par des appels à une fonction équivalente à
requeteAsynchrone()
.
Maintenant, je fais les mêmes vérifications que précédemment. Ci-dessous, je vérifie que la fonction listeDeRequete()
a toujours un comportement asynchrone.
Ci-dessous, je vérifie que mon application n'est pas bloquée en faisant manuellement un console.log
de 'Bonjour'
directement dans la console JavaScript.
Je constate que le console.log
s'intercale entre les requêtes bloquantes de la fonction asynchrone. 😏
On peut conclure en disant que async
/ await
permet d'écrire un code plus lisible et surtout moins verbeux.