Faire le quizz 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 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 fait le return d'un objet de constructeur Promise, c'est moi qui écrit l'exécuteur et enfin c'est moi qui déclenche l'appel à resolve. Je le fais après un délais 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élais est calculer par rapport à num multiplier par 1000 de manière à avoir un délais 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.