Objectifs de cette leçon
- Écrire des fonctions async
- Utiliser await pour attendre des Promises
- Gérer les erreurs avec try/catch
Async/Await en JavaScript 🚀
async/await est du sucre syntaxique par-dessus les promesses. Il rend le code asynchrone plus lisible — on dirait du code synchrone !
1. Les fonctions async ⚡
// Une fonction async retourne TOUJOURS une promesse async function direBonjour() { return "Bonjour !"; // Meme sans return explicite, c'est une promesse } // Appel direBonjour().then(message => console.log(message)); // "Bonjour !" console.log(direBonjour()); // Promise { <fulfilled>: "Bonjour !" }
2. Le mot-cle await ⏳
await attend qu'une promesse soit resolue. Il ne peut etre utilise QUE dans une fonction async :
async function fetchUser() { // await "pause" l'execution jusqu'a ce que la promesse soit resolue const reponse = await fetch("https://jsonplaceholder.typicode.com/users/1"); const user = await reponse.json(); console.log(user.name); return user; } // Equivalent avec .then() function fetchUserThen() { return fetch("https://jsonplaceholder.typicode.com/users/1") .then(r => r.json()) .then(user => { console.log(user.name); return user; }); }
3. Gestion d'erreurs avec try/catch 🛡️
async function fetchDonnees() { try { const reponse = await fetch("https://api.example.com/donnees"); if (!reponse.ok) { throw new Error(`Erreur HTTP : ${reponse.status}`); } const donnees = await reponse.json(); console.log("Donnees :", donnees); return donnees; } catch (erreur) { console.error("Erreur attrapee :", erreur.message); // On peut relancer ou retourner une valeur par defaut return null; } finally { console.log("Toujours execute"); } }
💡 Sans
async/await, la gestion d'erreurs avecthen/catchest moins lisible pour des sequences d'operations asynchrones.
4. Await avec fetch API 🌐
GET simple
async function getUsers() { try { const reponse = await fetch("https://jsonplaceholder.typicode.com/users"); const users = await reponse.json(); console.log(`${users.length} utilisateurs recus`); return users; } catch (erreur) { console.error("Erreur lors du fetch :", erreur); } }
POST avec donnees
async function creerPost(titre, corps, userId) { try { const reponse = await fetch("https://jsonplaceholder.typicode.com/posts", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title: titre, body: corps, userId }) }); const nouveauPost = await reponse.json(); console.log("Post cree :", nouveauPost.id); return nouveauPost; } catch (erreur) { console.error("Erreur :", erreur); } } // Utilisation creerPost("Mon titre", "Mon contenu", 1);
5. Requetes en parallele ⚡
// ❌ Mauvais — sequentiel (lent !) async function getDonneesSequentiel() { const users = await fetch("/api/users").then(r => r.json()); const posts = await fetch("/api/posts").then(r => r.json()); const comments = await fetch("/api/comments").then(r => r.json()); // Total : temps1 + temps2 + temps3 } // ✅ Bon — parallele (rapide !) async function getDonneesParallele() { const [users, posts, comments] = await Promise.all([ fetch("/api/users").then(r => r.json()), fetch("/api/posts").then(r => r.json()), fetch("/api/comments").then(r => r.json()) ]); // Total : max(temps1, temps2, temps3) return { users, posts, comments }; }
6. For await...of — iterer sur des promesses 🔁
const urls = [ "https://api.example.com/data1", "https://api.example.com/data2", "https://api.example.com/data3" ]; // Traite chaque reponse au fur et a mesure for await (const url of urls) { const reponse = await fetch(url); const donnees = await reponse.json(); console.log(donnees); }
7. Pattern : cache de donnees avec async ⏱️
const cache = new Map(); async function fetchAvecCache(url) { if (cache.has(url)) { console.log("Utilisation du cache pour", url); return cache.get(url); } console.log("Fetch depuis le reseau :", url); const reponse = await fetch(url); const donnees = await reponse.json(); cache.set(url, donnees); return donnees; } // Utilisation await fetchAvecCache("/api/users"); // Fetch reseau await fetchAvecCache("/api/users"); // Cache hit !
8. Pattern : retry avec async ⚡
async function fetchAvecRetry(url, tentatives = 3, delaiMs = 1000) { for (let i = 0; i < tentatives; i++) { try { const reponse = await fetch(url); if (!reponse.ok) throw new Error(`HTTP ${reponse.status}`); return await reponse.json(); } catch (erreur) { console.log(`Tentative ${i + 1}/${tentatives} echouee :`, erreur.message); if (i < tentatives - 1) { await new Promise(r => setTimeout(r, delaiMs * (i + 1))); } } } throw new Error(`${tentatives} tentatives echouees pour ${url}`); }
9. Comparaison syntaxe 📊
| Avantage | then/catch | async/await |
|---|---|---|
| Lisibilite | Moins lisible | Plus lisible |
| Debug | Plus dur | Plus facile (stack trace) |
| Gestion d'erreur | .catch() | try/catch |
| Parallele | Promise.all() | Promise.all() avec await |
| Conditions | Chaînage complexe | if/else classique |
| Boucles | .reduce() ou recursivité | for...of, for...in |
10. Exercices pour toi 🎯
Exercice 1 : API REST
Cree une fonction gererTodos() qui :
- Recupere tous les todos de
https://jsonplaceholder.typicode.com/todos - Filtre ceux qui sont completes
- Affiche les 5 premiers
Exercice 2 : Parallelisation Charge les donnees de 3 utilisateurs differents en parallele et affiche le plus rapide.
Exercice 3 : Rate limiter Implemente une fonction qui limite le nombre de requetes a N par seconde.
⚡ Simulateur — Async/Await
Étape 1/7async function déclare une fonction asynchrone. Elle retourne toujours une promesse et permet d'utiliser le mot-clé await à l'intérieur.