Asynchrone : Promises

Pourquoi JavaScript est asynchrone ?

Imaginez que vous commandez un plat au restaurant. Plutôt que de rester debout devant la cuisine en attendant que votre plat soit pret, vous retournez a votre table et continuez votre conversation. Le serveur viendra vous apporter le plat quand il sera pret. JavaScript fonctionne de la meme maniere : plutot que de bloquer tout le programme en attendant qu'une operation longue se termine (un appel reseau, une lecture de fichier...), il continue d'executer le reste du code et revient traiter le resultat quand il est disponible. C'est ce qu'on appelle l'asynchronisme.

Certaines operations prennent du temps (appels API, lecture de fichiers, timers) et ne bloquent pas l'execution du code. Cette page recapitule les bases des Promises et de async/await, que vous utiliserez avec useEffect dans les sections suivantes.

Qu'est-ce qu'une Promise ?

Une Promise représente une opération qui n'est pas encore terminée mais le sera dans le futur.

javascript
const promise = new Promise((resolve, reject) => {
  // Opération asynchrone
  setTimeout(() => {
    resolve('Success!');
    // ou reject('Error!') en cas d'erreur
  }, 1000);
});

États d'une Promise

  • Pending (en attente) : état initial
  • Fulfilled (résolue) : opération réussie
  • Rejected (rejetée) : opération échouée

Qu'est-ce qu'une Promise en JavaScript ?

.then() / .catch()

Méthode classique pour gérer les Promises.

javascript
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));

Chaîner les Promises

javascript
fetch('https://api.example.com/users/1')
  .then(response => response.json())
  .then(user => {
    console.log(user.name);
    return fetch(`https://api.example.com/posts?userId=${user.id}`);
  })
  .then(response => response.json())
  .then(posts => console.log(posts))
  .catch(error => console.error(error));

async/await

Syntaxe recommandée pour le code asynchrone.

Fonction async

javascript
const fetchData = async () => {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
};

fetchData();

Mot-clé async

javascript
// Fonction fléchée async
const myFunction = async () => {
  // ...
};

// Fonction classique async
async function myFunction() {
  // ...
}

Mot-clé await

await met en pause l'exécution jusqu'à ce que la Promise soit résolue.

javascript
// ❌ Sans await (retourne une Promise)
const data = fetch('https://api.example.com/data');
console.log(data); // Promise { <pending> }

// ✅ Avec await (attend la réponse)
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data); // { ... } (données réelles)

Attention

await ne peut être utilisé qu'à l'intérieur d'une fonction async !

javascript
// ❌ Erreur
const data = await fetch('/api/data');

// ✅ OK
const fetchData = async () => {
  const data = await fetch('/api/data');
};

Quelle est la différence entre .then() et async/await ?

Gestion d'erreurs

try/catch

javascript
const fetchUser = async (id) => {
  try {
    const response = await fetch(`/api/users/${id}`);

    if (!response.ok) {
      throw new Error('User not found');
    }

    const user = await response.json();
    return user;
  } catch (error) {
    console.error('Error:', error.message);
    return null;
  }
};

.catch() avec async/await

javascript
const fetchData = async () => {
  const data = await fetch('/api/data')
    .then(res => res.json())
    .catch(error => {
      console.error(error);
      return null;
    });

  return data;
};

Et en React ?

Dans la section Data Fetching, vous verrez comment utiliser async/await avec useEffect pour faire des appels API dans vos composants React.

Pour aller plus loin : Promise.all()

Quand vous serez a l'aise avec les Promises, sachez que Promise.all() permet d'attendre plusieurs Promises en parallele. C'est plus rapide que d'attendre les Promises une par une :

javascript
// ❌ Lent (séquentiel) - 3 secondes
const users = await fetch('/api/users');
const posts = await fetch('/api/posts');
const comments = await fetch('/api/comments');

// ✅ Rapide (parallèle) - 1 seconde
const [users, posts, comments] = await Promise.all([
  fetch('/api/users'),
  fetch('/api/posts'),
  fetch('/api/comments')
]);

Vous verrez ce pattern en action dans la section Combiner useEffect & Routing.

setTimeout avec Promises

javascript
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

const example = async () => {
  console.log('Start');
  await delay(2000); // Attend 2 secondes
  console.log('2 seconds later');
};

example();

Résumé

ConceptDescription
PromiseObjet représentant une opération asynchrone
asyncDéclare une fonction asynchrone
awaitAttend qu'une Promise soit résolue
try/catchGère les erreurs en async/await
.then()Méthode classique pour les Promises
.catch()Gère les erreurs avec .then()

Comprendre, pas mémoriser

Ce qu'il faut retenir :

  • Promise → objet representant une operation asynchrone future
  • async/await → syntaxe lisible pour travailler avec les Promises
  • try/catch → gerer les erreurs en code asynchrone
  • await → met en pause jusqu'a ce que la Promise soit resolue

Avec la pratique et useEffect, ces patterns deviendront naturels. Consultez MDN si vous avez un doute sur la syntaxe.