3e étageJS JavaScriptPièce 6/7Avancé

Asynchrone et modules

Gérer ce qui prend du temps avec les promesses, async et await, charger des données avec fetch, puis découper son code avec import et export.

Ce que tu vas apprendre

  • Comprendre pourquoi certaines opérations sont asynchrones.
  • Utiliser les promesses, async et await et charger des données avec fetch.
  • Répartir ton code dans plusieurs fichiers avec import et export.

Pourquoi de l'asynchrone

Charger des recettes depuis un serveur prend du temps. Si JavaScript attendait la réponse sans rien faire, la page serait figée.

Une opération asynchrone est lancée, puis ton code continue. Le résultat arrive plus tard, et le navigateur te prévient.

console.log('1 : début')

setTimeout(() => {
  console.log('3 : deux secondes plus tard')
}, 2000)

console.log('2 : la suite continue')

Les messages s'affichent dans l'ordre 1, 2, puis 3. setTimeout lance un minuteur sans bloquer le reste.

Les promesses

Une promesse (Promise) représente un résultat qui n'est pas encore disponible. Elle est dans l'un de ces trois états : en attente, tenue (résolue) ou rompue (rejetée).

Tu lui accroches des fonctions avec then pour le succès et catch pour l'échec.

fetch('/api/recettes')
  .then((reponse) => reponse.json())
  .then((recettes) => console.log(recettes))
  .catch((erreur) => console.error(erreur))

Chaque then reçoit le résultat du précédent. Cette chaîne fonctionne, mais devient vite difficile à lire.

async et await

async et await donnent à une promesse l'allure d'un code ordinaire. Le mot-clé await met la fonction en pause jusqu'à ce que la promesse soit terminée. Il s'utilise dans une fonction marquée async.

async function chargerRecettes() {
  const reponse = await fetch('/api/recettes')
  const recettes = await reponse.json()
  return recettes
}

Une fonction async renvoie toujours une promesse. Pour récupérer sa valeur, utilise await à nouveau, ou then.

Gérer les erreurs

Avec await, une promesse rompue lève une erreur que tu attrapes avec try et catch.

async function afficherRecettes() {
  try {
    const recettes = await chargerRecettes()
    console.log(recettes.length)
  } catch (erreur) {
    console.error('Chargement impossible', erreur)
  }
}

Le bloc catch s'exécute si une erreur survient dans le try.

fetch

fetch(url) envoie une requête HTTP et renvoie une promesse qui donne un objet Response. reponse.json() lit le corps de la réponse et le convertit en objet.

fetch ne rejette pas la promesse sur une erreur HTTP comme 404 ou 500. Elle n'est rompue qu'en cas de problème réseau. Teste toi-même reponse.ok.
const reponse = await fetch('/api/recettes/99')

if (!reponse.ok) {
  throw new Error(`Erreur ${reponse.status}`)
}

Envoyer des données

Pour envoyer une recette, ajoute des options : la méthode, un en-tête et le corps converti en JSON.

await fetch('/api/recettes', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ titre: 'Crêpes', minutes: 20 })
})

Plusieurs requêtes en parallèle

Deux await à la suite attendent l'un après l'autre. Promise.all lance tout en même temps et attend la fin de toutes.

const [recettes, ingredients] = await Promise.all([
  fetch('/api/recettes').then((r) => r.json()),
  fetch('/api/ingredients').then((r) => r.json())
])

Les modules

Un module est un fichier JavaScript qui expose des éléments à d'autres fichiers. Tu découpes ton code, chaque fichier a un rôle précis.

prix.js
export const TVA = 0.055

export function prixTTC(prixHT) {
  return prixHT * (1 + TVA)
}

export default function formaterPrix(valeur) {
  return `${valeur.toFixed(2)} €`
}
script.js
import formaterPrix, { prixTTC, TVA } from './prix.js'

console.log(formaterPrix(prixTTC(10)))

Les exports nommés s'importent entre accolades, avec le même nom. L'export default s'importe sans accolades, sous le nom de ton choix. Un fichier n'en a qu'un.

Utiliser les modules dans une page

Dans le navigateur, déclare ton script avec type="module".

index.html
<script type="module" src="script.js"></script>

Un script de type module est exécuté après la lecture de la page, comme avec defer. Ses variables restent privées au fichier.

Les modules ne fonctionnent pas en ouvrant le fichier directement (adresse file://). Lance un petit serveur local, ou utilise un outil comme Vite ou Nuxt qui s'en charge.

À retenir

  • Une opération asynchrone ne bloque pas le reste du code : le résultat arrive plus tard.
  • Une promesse est tenue ou rompue, then et catch en lisent le résultat.
  • await attend une promesse dans une fonction async, try et catch gèrent les erreurs.
  • fetch ne rejette pas sur un 404 ou un 500 : vérifie reponse.ok.
  • Promise.all lance plusieurs opérations en parallèle.
  • export expose, import récupère, et <script type="module"> active les modules dans la page.

Pour aller plus loin

Sources officielles

Ensuite

Projet
Lignes de code
Niveau
3e étage
Appartement
JavaScript
Pièce
6/7
Plan n°
js/06.asynchrone-et-modules
Lignes de code · fiches rédigées à partir des documentations officielles, sources citées en bas de chaque page.