Initialisation des systèmes...

Baptiste.Dev
Retour aux notes
LangagesIntermédiaireSérie : JavaScript

JavaScript : L'asynchrone

Pourquoi JavaScript est asynchrone, et comment le gérer : callbacks, promesses, async / await et fetch pour appeler une API sans bloquer la page.

Par Baptiste Vidal
3 min de lecture
Mis à jour il y a 2 semaines
javascriptjsasynchronepromessesasync-awaitfetch

JavaScript : L'asynchrone

Certaines opérations prennent du temps : appeler une API, lire un fichier, attendre un délai. Le problème, c'est que JavaScript est monothread : il n'exécute qu'une chose à la fois. Comment attendre un résultat lent sans figer toute la page ? C'est tout l'enjeu de l'asynchrone.


# Le problème : ne pas bloquer

JavaScript s'exécute sur un seul fil d'exécution. Si une opération longue s'exécutait de façon bloquante, toute la page serait gelée pendant ce temps : plus aucun clic, plus aucune animation, rien.

La solution : lancer l'opération, continuer le reste du code, et réagir plus tard, quand le résultat est prêt. C'est ça, l'asynchrone : « fais ça, et préviens-moi quand c'est fini ».


# Les callbacks (l'ancienne façon)

Historiquement, on passait une fonction de rappel (callback), exécutée une fois l'opération terminée. L'exemple le plus simple, un délai :

setTimeout(() => {
  console.log("2 secondes plus tard");
}, 2000);
 
console.log("Ceci s'affiche en premier");

Ça marche, mais dès qu'on enchaîne plusieurs opérations dépendantes, le code s'imbrique en pyramide (le fameux callback hell) et devient illisible. D'où l'arrivée des promesses.


# Les promesses (Promise)

Une promesse représente une valeur future : un résultat qui n'est pas encore là, mais qui finira par arriver (ou par échouer). Elle a trois états :

ÉtatSignification
pendingEn attente, l'opération est en cours
fulfilledRéussie, la valeur est disponible
rejectedÉchouée, une erreur est survenue

On réagit avec .then() (succès) et .catch() (erreur) :

fetch("/api/projets")
  .then((reponse) => reponse.json())
  .then((data) => console.log(data))
  .catch((erreur) => console.error("Échec :", erreur));

Chaque .then() renvoie une nouvelle promesse, ce qui permet de chaîner les étapes proprement, sans imbrication.


# async / await (la façon moderne)

async / await est du sucre syntaxique au-dessus des promesses. Il permet d'écrire du code asynchrone qui se lit comme du code synchrone, de haut en bas.

Sucre syntaxique : une écriture plus agréable pour faire quelque chose qui existe déjà, sans rien ajouter sous le capot. async / await ne remplace pas les promesses - il les habille pour les rendre plus lisibles.

async function chargerProjets() {
  try {
    const reponse = await fetch("/api/projets");
    const data = await reponse.json();
    console.log(data);
  } catch (erreur) {
    console.error("Échec :", erreur);
  }
}

Deux règles :

  • Le mot-clé await s'utilise à l'intérieur d'une fonction async.
  • await met en pause la fonction jusqu'à ce que la promesse soit résolue, sans bloquer le reste de la page.
  • La gestion d'erreur passe par un bloc try / catch, comme pour du code classique.

C'est la forme qu'on privilégie aujourd'hui : plus lisible que les chaînes de .then().


# fetch : appeler une API

fetch est la fonction intégrée pour faire des requêtes réseau. Elle renvoie une promesse, donc elle se marie parfaitement avec async / await.

API (Application Programming Interface) : un point d'entrée qui permet à un programme d'en interroger un autre. Ici une API web : on envoie une requête à une URL, le serveur renvoie des données (souvent en JSON).

async function getUtilisateur(id) {
  const reponse = await fetch(`https://api.exemple.fr/users/${id}`);
 
  if (!reponse.ok) {
    throw new Error(`Erreur HTTP : ${reponse.status}`);
  }
 
  return reponse.json();
}

fetch ne rejette la promesse qu'en cas d'erreur réseau. Un code 404 ou 500 est considéré comme une réponse « reçue » : c'est à toi de vérifier reponse.ok et de gérer le cas. Ce portfolio fait exactement ça pour interroger l'API GitHub.


# À retenir

  • JavaScript est monothread : l'asynchrone évite de bloquer la page pendant une opération longue.
  • Une promesse représente une valeur future (.then() / .catch()).
  • async / await rend le code asynchrone lisible, avec la gestion d'erreur en try / catch.
  • fetch sert à appeler une API. Pense à vérifier reponse.ok.

Ces réflexes se retrouvent directement en React et Next.js, où récupérer des données (dans un Server Component async, par exemple) repose sur exactement les mêmes outils.