{}const=>[]async()letfn</>var
DéveloppementJS

Les promesses en JavaScript : le guide complet de l'asynchronisme

Comprendre Promise en JavaScript : trois états de promesses, chaînes then/catch/finally, méthodes Promise.all et Promise.race. Exemples pratiques, erreurs courantes et meilleures pratiques de travail avec le code asynchrone pour les développeurs.

К

Kodik

Auteur

7 min de lecture

Qu'est-ce que Promise

Promise est un objet représentant le résultat d'une opération asynchrone qui peut être obtenue maintenant, dans le futur ou jamais. C'est une sorte de « promesse » de retourner le résultat lorsque l'opération est terminée.

Promis existe dans l'un des trois états :

  • pending (en attente) — état initial, l'opération est toujours en cours

  • fulfilled (terminé) — l'opération s'est terminée avec succès

  • rejected (rejeté) — l'opération s'est terminée par une erreur

Il est important de comprendre qu'une promesse ne peut passer de l'état pending qu'une seule fois, soit à l'état fulfilled, soit à l'état rejected. Après cela, l'état ne change pas.

🔥 100 000+ étudiants déjà avec nous

Marre de lire la théorie ?
Il est temps de coder !

Kodik — une appli où tu apprends à coder par la pratique. Mentor IA, leçons interactives, projets réels.

🤖 IA 24/7
🎓 Certificats
💰 Gratuit
🚀 Commencer
Ont rejoint aujourd'hui

Création d'une promesse

Une promesse est créée à l'aide du constructeur Promise, qui accepte la fonction d'exécution (executor). Cette fonction reçoit deux arguments : resolve et reject.

const myPromise = new Promise((resolve, reject) => {
  // Opération asynchrone
  const success = true;
  
  if (success) {
    resolve('The operation was successful!');
  } else {
    reject('An error occurred');
  }
});

La fonction d'exécution démarre immédiatement lors de la création de la promesse. Lorsque vous appelez resolve(value), la promesse passe à l'état fulfilled avec le résultat value. Lors de l'appel de reject(error), la promesse passe à rejected avec l'erreur error.

Traitement des résultats : then, catch, finally

Pour travailler avec le résultat de la promesse, on utilise les méthodes then, catch et finally.

myPromise
  .then(result => {
    console.log('Success:', result);
    return result.toUpperCase();
  })
  .catch(error => {
    console.error('Error:', error);
  })
  .finally(() => {
    console.log('Operation completed');
  });

La méthode then accepte deux arguments facultatifs : un rappel pour une exécution réussie et un rappel pour une erreur. En pratique, pour le traitement des erreurs, on utilise plus souvent catch, ce qui rend le code plus lisible.

La méthode finally est toujours exécutée, quel que soit le résultat de la promesse. C'est pratique pour les actions qui doivent être effectuées dans tous les cas, par exemple, masquer l'indicateur de chargement.

Chaînes de promesses

L'un des principaux avantages des promesses est la possibilité de créer des chaînes d'opérations asynchrones. Chaque then renvoie une nouvelle promesse, ce qui vous permet de construire des séquences.

fetch('https://api.example.com/user/1')
  .then(response => response.json())
  .then(user => {
    console.log('Username:', user.name);
    return fetch(`https://api.example.com/user/${user.id}/posts`);
  })
  .then(response => response.json())
  .then(posts => {
    console.log('User posts:', posts);
  })
  .catch(error => {
    console.error('Error in the chain:', error);
  });

Dans la chaîne de promesses, une erreur à n'importe quelle étape « échoue » au catch le plus proche. Cela permet de traiter les erreurs de manière centralisée.

Exemple pratique : chargement des données

Prenons un scénario réel : le chargement des données utilisateur depuis le serveur avec le traitement de différentes situations.

function fetchUserData(userId) {
  return new Promise((resolve, reject) => {
    // Simulation de retard du réseau
    setTimeout(() => {
      const users = {
        1: { name: 'Alexey', role: 'developer' },
        2: { name: 'Maria', role: 'designer' }
      };
      
      const user = users[userId];
      
      if (user) {
        resolve(user);
      } else {
        reject(new Error('User not found'));
      }
    }, 1000);
  });
}

// Utilisation
fetchUserData(1)
  .then(user => {
    console.log(`Hi ${user.name}!`);
    console.log(`Your role: ${user.role}`);
  })
  .catch(error => {
    console.error('Failed to load data:', error.message);
  })
  .finally(() => {
    console.log('Request completed');
  });

Promise.all et Promise.race

JavaScript fournit des méthodes statiques utiles pour travailler avec de nombreux promesses.

Promise.all

La méthode Promise.all prend un tableau de promesses et renvoie une nouvelle promesse qui est exécutée lorsque toutes les promesses du tableau sont exécutées. Si au moins une promesse est rejetée, l'ensemble du Promise.all est rejeté.

const promise1 = Promise.resolve(3);
const promise2 = new Promise(resolve => setTimeout(() => resolve(42), 1000));
const promise3 = fetch('https://api.example.com/data').then(r => r.json());

Promise.all([promise1, promise2, promise3])
  .then(results => {
    console.log('All results:', results);
    // results sera un tableau : [3, 42, {...données de l'API}]
  })
  .catch(error => {
    console.error('One of the promisses ended in error:', error);
  });

C'est pratique lorsque vous devez effectuer plusieurs opérations asynchrones indépendantes et attendre qu'elles soient toutes terminées.

Promise.race

La méthode Promise.race renvoie une promesse qui est exécutée ou rejetée dès que la première des promesses transmises est exécutée ou rejetée.

const slowPromise = new Promise(resolve => 
  setTimeout(() => resolve('Slow'), 3000)
);
const fastPromise = new Promise(resolve => 
  setTimeout(() => resolve('Fast'), 1000)
);

Promise.race([slowPromise, fastPromise])
  .then(result => {
    console.log('Winner:', result); // 'Rapide'});

Ceci est utile pour la mise en œuvre des délais d'attente ou pour sélectionner la source de données la plus rapide.

Promise.allSettled et Promise.any

Les versions modernes de JavaScript ont ajouté deux autres méthodes utiles.

Promise.allSettled

Contrairement à Promise.all, la méthode Promise.allSettled attend la fin de toutes les promesses, quel que soit le résultat. Renvoie un tableau d'objets avec des informations sur chaque promesse.

const promises = [
  Promise.resolve('Success'),
  Promise.reject('Error'),
  Promise.resolve('More success')
];

Promise.allSettled(promises)
  .then(results => {
    results.forEach((result, index) => {
      if (result.status === 'fulfilled') {
        console.log(`Promis ${index}: executed with value ${result.value}`);
      } else {
        console.log(`Promo ${index}: rejected with reason ${result.reason}`);
      }
    });
  });

Promise.any

La méthode Promise.any renvoie la première promesse exécutée avec succès. Si toutes les promesses sont rejetées, la promesse rejetée est renvoyée avec une erreur agrégée.

const promises = [
  Promise.reject('Error 1'),
  Promise.resolve('Success'),
  Promise.reject('Error 2')
];

Promise.any(promises)
  .then(result => {
    console.log('First successful result:', result); // Succèss'
  })
  .catch(error => {
    console.error('All promissory notes are rejected:', error);
  });

Erreurs typiques lors de l'utilisation de promesses

Retour oublié dans la chaîne

Une erreur courante est d'oublier de retourner la promesse de then, ce qui brise la chaîne.

// Incorrect
fetchUser()
  .then(user => {
    fetchPosts(user.id); // Vous avez oublié return !
  })
  .then(posts => {
    // les messages seront indéfinis
    console.log(posts);
  });

// Correct
fetchUser()
  .then(user => {
    return fetchPosts(user.id); // Nous retournons la prime
  })
  .then(posts => {
    console.log(posts); // Maintenant, les messages contiennent des données
  });

Promesses imbriquées au lieu de chaînes

Parfois, les développeurs créent une imbrication de promesses, ce qui nous ramène au problème du callback-hell.

// Mauvais - imbrication
fetchUser()
  .then(user => {
    fetchPosts(user.id)
      .then(posts => {
        fetchComments(posts[0].id)
          .then(comments => {
            console.log(comments);
          });
      });
  });

// Bien — chaîne
fetchUser()
  .then(user => fetchPosts(user.id))
  .then(posts => fetchComments(posts[0].id))
  .then(comments => console.log(comments))
  .catch(error => console.error(error));

Absence de traitement des erreurs

Toujours ajouter catch pour gérer les erreurs, sinon elles peuvent passer inaperçues.

// Dangereux
fetchData().then(data => console.log(data));

// Sécurisé
fetchData()
  .then(data => console.log(data))
  .catch(error => console.error('An error occurred:', error));

Des promesses à async/await

Les promesses ont posé les bases de la syntaxe async/await, qui rend le code asynchrone encore plus similaire au code synchrone.

// Avec des promesses
function getUserInfo() {
  return fetchUser()
    .then(user => fetchPosts(user.id))
    .then(posts => {
      return { user, posts };
    });
}

// Avec async/await
async function getUserInfo() {
  const user = await fetchUser();
  const posts = await fetchPosts(user.id);
  return { user, posts };
}

Cependant, la compréhension des promesses est critique, car async/await est un sucre syntaxique sur les promesses, et la connaissance de leur travail aide à utiliser efficacement l'asynchronisme en JavaScript.

Conclusion

Les promesses ont résolu le problème fondamental de JavaScript : un travail élégant avec des opérations asynchrones. Elles fournissent une interface claire pour contrôler la séquence des actions, gérer les erreurs et composer des opérations asynchrones.

Points clés à retenir :

  • Promis est dans l'un des trois états et ne le change qu'une seule fois

  • Les chaînes de promesses résolvent le problème de l'imbrication des callbacks

  • Traitez toujours les erreurs via catch

  • Utilisez Promise.all pour exécuter des opérations indépendantes en parallèle

  • Renvoyez les promesses de then pour construire des chaînes correctes

Une compréhension approfondie des promesses est la base pour travailler avec le JavaScript asynchrone moderne et la transition vers async/await.

Vous voulez organiser vos connaissances ? Sur la plateforme Code vous trouverez des cours pratiques de programmation avec du certificat à la fin de la formation.

Rejoignez notre chaîne Telegram confortable — ici, nous partageons des ressources utiles, discutons de sujets intéressants et aidons les développeurs débutants à se développer professionnellement. Apprendre ensemble est plus amusant !

🎯Arrête de reporter

Tu as aimé l'article ?
Place à la pratique !

Avec Kodik, tu ne lis pas seulement — tu codes immédiatement. Théorie + pratique = vraies compétences.

Pratique instantanée
🧠L'IA explique le code
🏆Certificat

Sans inscription • Sans carte