Faire le quiz link W3C close

ASYNC / AWAIT

#1 Comment s'utilise async / await ? open

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.

Règles d'usage d'async / await

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 :

  1. Le constructeur n'est pas le même que celui des fonctions classiques. C'est le constructeur AsyncFunction.
  2. Justement ce constructeur est dérivé de celui des fonctions classiques.
  3. Cependant, un typeof ne fait pas la différence et renvoie toujours la chaîne 'function'.
  4. 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.
Spécificités d'une fonction déclarée avec async

#2 Exemple d'utilisation d'async / await. open

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 ?

  1. 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 le return d'un objet de constructeur Promise, 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 utilisant setTimeout. L'argument num, on peut le voir comme le numéro de la requête. Et enfin le délai est calculé par rapport à num multiplier par 1000 de manière à avoir un délai en millisecondes.
  2. 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'appelle requeteAsynchrone(1) et je traite le résultat dans le then qui est collé derrière. Dans ce then, je vais enchaîner une deuxième opération asynchrone en appelant requeteAsynchrone(res_1+1) après avoir obtenu le résultat de requeteAsynchrone(1). Je me sers de ce résultat pour simulation. Le résultat res_1+1 vaudra 2.
  3. Ensuite, je continue de la même manière avec les opérations qui suivent.
  4. 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é.
Tester le code

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.

Vérification que la fonction est asynchrone

Ci-dessous, je fais un console.log('Bonjour') manuellement pour vérifier que mon application n'est pas bloquée.

Vérification que l'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().
Tester le code

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.

Vérification que la fonction est 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. 😏

Vérification que l'application n'est pas bloquée

On peut conclure en disant que async / await permet d'écrire un code plus lisible et surtout moins verbeux.