Aller au contenu

async/await

Le moteur Javascript V8, utilisé par les tous les navigateurs modernes ainsi que Node, a imposé un style de programmation s'appuyant lourdement sur du code asynchrone.

Fonctions asynchrones

Javascript permet de définir des fonctions asynchrones. Une fonction asynchrone renvoie non pas une valeur "simple", mais plutôt un objet Promise, qui peut être résolu ou annulé ultérieurement.

La fonction fetch en est un bon exemple, elle renvoie des données via deux promises successives :

export function getUsers() {
  fetch('/api/users')
    .then(res => res.json())
    .then(data => setUsers(data));  // ou simplement : .then(setUsers)
}
  1. Quand une réponse arrive, on commence à la traiter (décodage en tant que JSON).
  2. Quand les données ont été complètement décodées, on les utilise (ici, stockage dans une varialbe d'état).

On ne peut pas utiliser cette fonction de manière synchrone, si on essaie, on obtient immédiatement une valeur nulle (à supposer qu'aucune erreur ne soit générée), et la requête HTTP ne sera probablement même pas exécutée :

Incorrect !!!

export function getUsers() {
  const out = fetch('/api/users');
  return out.json();
}

async / await : une syntaxe améliorée pour définir des fonctions asynchrones

Principes : * permettre d'éviter d'écrire des appels de promises (.then()) * permettre d'avoir un code plus lisible ("pseudo-synchrone"), dans lequel l'ordre d'exécution correspond à l'ordre du code source

Mise en œuvre : * La fonction utilise le mot clé async dans sa définition * Les appels asynchrones dans le corps de la fonction sont précédés du mot clé await.

export async function getUsers() {
  const res = await fetch('/api/users');
  setUsers(await res.json());
}
  • Le premier await attend que la réponse brute soit disponible.
  • Le second await attend que le décodage du JSON soit terminé, pour pouvoir stocker le résultat dans une variable d'état.

Traitement d'erreur

Les syntaxes .then() et .catch() ne sont pas applicables ici, on passe par un bloc try ... catch (traitement d'exceptions) :

export async function getUsers() {
  try {
    const res = await fetch('/api/users');
    setUsers(await res.json());
  }
  catch(error){
    // Traitement commun des erreurs
    console.log(error.msg);
  }
}