Comprendre les Promesses, Async/Await et Promise.all
en JavaScript
Les Promesses en JavaScript
Une promesse est un objet qui représente une opération asynchrone dont le résultat peut être disponible à l’avenir. Elle peut être :
- Résolue (fulfilled) : l’opération a réussi.
- Rejetée (rejected) : l’opération a échoué.
- En attente (pending) : l’opération est en cours.
Avantage : Permet de gérer efficacement les opérations asynchrones.
Risque : La gestion avec .then()
et .catch()
peut devenir difficile à lire en cas de nombreuses promesses imbriquées (callback hell).
Exemple simple d’une promesse :
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true; // Simulons un succès
if (success) resolve("Données récupérées avec succès !");
else reject("Erreur lors de la récupération des données");
}, 1000);
});
}
fetchData()
.then(result => console.log(result))
.catch(error => console.error(error));
Async/Await : Une syntaxe simplifiée pour gérer les promesses
async/await
est une alternative plus lisible à la gestion classique des promesses avec .then()
et .catch()
. Les fonctions marquées avec async
renvoient toujours une promesse. La clé await
suspend l’exécution du code jusqu’à ce que la promesse soit résolue ou rejetée.
Avantage : Améliore la lisibilité et facilite la gestion des erreurs avec try/catch
.
Risque : Si une opération dépend trop de await
successifs, le code peut devenir plus lent qu’avec des opérations parallèles.
Exemple :
async function getData() {
try {
const result = await fetchData();
console.log(result);
} catch (error) {
console.error(error);
}
}
getData();
Promise.all : Exécuter plusieurs promesses en parallèle
Promise.all
permet de lancer plusieurs opérations asynchrones en parallèle. Il renvoie une seule promesse qui est résolue lorsque toutes les promesses sont réussies ou rejetée si l’une échoue.
Avantage : Très rapide lorsque toutes les opérations sont indépendantes.
Risque : Si une seule promesse échoue, Promise.all
rejette immédiatement toutes les autres.
Exemple :
const promise1 = new Promise(resolve => setTimeout(() => resolve("Promesse 1"), 1000));
const promise2 = new Promise(resolve => setTimeout(() => resolve("Promesse 2"), 2000));
Promise.all([promise1, promise2])
.then(results => console.log("Résultats :", results))
.catch(error => console.error("Erreur :", error));
Stratégies d’utilisation
1. Exécution en série (Series)
Chaque tâche est exécutée une par une, idéale lorsque les opérations dépendent les unes des autres.
async function series(tasks) {
for (const task of tasks) {
await task();
}
console.log("Série terminée");
}
2. Exécution en parallèle totale (Full Parallel)
Les tâches sont exécutées en même temps, parfait lorsque les opérations sont indépendantes.
async function fullParallel(tasks) {
await Promise.all(tasks.map(task => task()));
console.log("Toutes les tâches sont terminées");
}
3. Exécution en parallèle limitée (Limited Parallel)
Limite le nombre de tâches exécutées en parallèle, utile pour préserver les ressources système.
async function limitedParallel(tasks, limit) {
const running = [];
for (const task of tasks) {
const promise = task();
running.push(promise);
if (running.length >= limit) {
await Promise.race(running);
running.splice(0, running.findIndex(p => p === promise) + 1);
}
}
await Promise.all(running);
console.log("Toutes les tâches limitées sont terminées");
}
Avec ces explications et exemples, vous êtes prêt à maîtriser les promesses et les flux de contrôle asynchrones en JavaScript !