Advanced Typescript
Javascript/Promises

Async/Await

Il existe une syntaxe spéciale pour utiliser les promesses d'une manière plus simple appelée “async/await”.

async

Commençons par le mot-clé async.
Il peut être placé avant une fonction, comme ceci:

async function hello() {
  return 'hello';
}

ou alors sur une fonction fléchée de la manière suivante:

const hello = async () => {
  return 'hello';
}

La présence du mot clé async implique que cette fonction retournera obligatoirement un objet de type Promise.
Comme nous l'avons vu dans le chapittre précédent, nous pourrons utiliser le constructeur Promise et ses fonctions associées pour la résoudre.
Par exemple avec l'exemple précédent:

async function hello() {
  return 'hello';
}

hello.then(console.log); // Affichera "hello" en console

await

La syntaxe:

const value = await promise;

Le mot-clé await fait en sorte que JavaScript attende que cette promesse se résolve et renvoie son résultat.

Voici un exemple avec une promesse qui se résout en 1 seconde:

async function f() {
  const promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });

  const result = await promise; 

  console.log(result); // "done!"
}

f();

L'exécution de la fonction fait une “pause” à la ligne 6 et reprend lorsque la promesse est résolue, result devenant son résultat.
Ainsi le code ci-dessus affiche “done!” en une seconde.

await suspend littéralement l'exécution de la fonction jusqu'à ce que la promesse soit résolue, puis la reprend avec le résultat de la promesse.
Cela ne coûte pas de ressources CPU, car le moteur JavaScript peut faire d'autres travaux pendant ce temps : exécuter d'autres scripts, gérer des événements, etc.

C'est juste une syntaxe plus élégante pour obtenir le résultat de la promesse que promise.then. Et c'est plus facile à lire et à écrire.

Exemple

Pour appeler une API par exemple, le client doit attendre la réponse du serveur.
On peut donc utiliser cette syntaxe:

async function getData() {
  const req = await fetch('https://jsonplaceholder.typicode.com/todos/1')
  const res = await req.json()

  console.log(res) // {"userId": 1,"id": 1,"title": "delectus aut autem","completed": false}
}

Il est possible que l'appel HTTP parte en erreur.
Dans ce cas là on peut englober ce bloc d'un try {} catch {}

async function getData() {
  try { 
    const req = await fetch('https://jsonplaceholder.typicode.com/todos/1')
    const res = await req.json()
  
    console.log(res) // {"userId": 1,"id": 1,"title": "delectus aut autem","completed": false}
    return res
  } catch(e) {
    console.error(e);
    return null
  }
}

Exercice : Créer une Carte de Profil GitHub 🧑‍💻

L'idée va être de créer un formulaire qui permet de rechercher un utilisateur GitHub et d'afficher sa carte de profil en utilisant async/await pour gérer l'appel à l'API.

L'API GitHub

Nous utiliserons l'API publique de GitHub. L'URL pour récupérer un utilisateur est la suivante : https://api.github.com/users/NOM_UTILISATEUR

Remplacez NOM_UTILISATEUR par un pseudo GitHub (par exemple, torvalds pour Linus Torvalds).

Les données qui nous intéressent dans la réponse sont :

  • avatar_url : L'URL de l'image de profil.
  • name : Le nom complet de l'utilisateur.
  • bio : Sa biographie.
  • public_repos : Le nombre de dépôts publics.

Dans votre fichier index.html, mettez en place une structure simple :

Un formulaire (<form>) contenant :

  • Un champ de saisie (<input type="text">) pour le nom d'utilisateur.
  • Un bouton (<button type="submit">) pour lancer la recherche.
  • Une div qui servira de conteneur pour afficher la carte de profil.

Partez du projet Vanilla JS ci dessous.