Promises et async/await
then/catch, async/await, erreurs et parallélisme.
Objectifs
À la fin de cette leçon, vous saurez :
- consommer une Promise avec then/catch ;
- écrire du code asynchrone lisible avec async/await ;
- gérer les erreurs asynchrones correctement.
La Promise : un reçu pour une valeur à venir
Une Promise est un objet qui représente le résultat futur d'une opération. Trois états :
pending → en cours
fulfilled → terminé avec succès (une valeur)
rejected → terminé en échec (une erreur)
then / catch : la consommation de base
lireFichierAsync("notes.txt")
.then(function (contenu) {
console.log("Reçu :", contenu);
})
.catch(function (erreur) {
console.error("Échec :", erreur.message);
});
.then s'enchaîne : chaque étape reçoit le résultat de la précédente, et une erreur saute jusqu'au .catch le plus proche — exactement comme les exceptions synchrones.
async / await : la même chose, plus lisible
Devant toute fonction renvoyant une Promise, on peut poser await — dans une fonction marquée async :
async function afficherNotes() {
try {
const contenu = await lireFichierAsync("notes.txt");
console.log("Reçu :", contenu); // attendu VRAIMENT
const analyse = await analyser(contenu); // séquentiel naturel
return analyse;
} catch (erreur) {
console.error("Échec :", erreur.message);
}
}
Le code se lit comme du synchrone ; await suspend la fonction sans bloquer le fil (les autres tâches continuent — c'est l'event loop qui gère). Sous le capot, async renvoie toujours une Promise.
Paralléliser quand c'est possible
Deux lectures indépendantes ne devraient pas s'attendre mutuellement :
// Séquentiel : 2 × le temps // Parallèle : ~1 × le temps
const a = await lireA(); const [a, b] = await Promise.all([
const b = await lireB(); lireA(),
lireB(),
]);
Promise.all attend que toutes soient prêtes (et échoue dès la première erreur). Règle : séquentiel seulement quand B a besoin du résultat de A.
Les pièges classiques
// Oublier await : la Promise reste pendante, erreurs silencieuses
sauvegarder(); // ⚠️ rien n'attend le résultat
await sauvegarder(); // ✅
// await dans une boucle alors que c'est parallélisable
for (const id of ids) { await traiter(id); } // lent
await Promise.all(ids.map((id) => traiter(id))); // rapide
Exercice
- Écrivez
attendre(ms)qui résout après ms millisecondes (setTimeout+ Promise). - Avec elle, faites défiler « 3… 2… 1… Décollage » à une seconde d'intervalle.
- Transformez une chaîne de
.then()donnée en version async/await. - Lancez trois
attendre(1000)en parallèle : vérifiez que tout dure ~1 s.
Résumé
- Promise = résultat futur à trois états.
- async/await = syntaxe synchrone sur mécanisme asynchrone ; try/catch gère les échecs.
- Promise.all pour le parallèle ; jamais d'await oublié.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
Question 1.
function attendre(ms) {
return new Promise(function (resoudre) {
setTimeout(resoudre, ms);
});
}
await attendre(1000);
console.log("une seconde plus tard");
Question 2.
async function decompte() {
for (let i = 3; i >= 1; i--) {
console.log(i);
await attendre(1000);
}
console.log("Décollage");
}
Question 4.
const debut = Date.now();
await Promise.all([attendre(1000), attendre(1000), attendre(1000)]);
console.log(Date.now() - debut); // ≈ 1000, pas 3000