Complétez les exercices dans votre éditeur (VSCode) et testez-les dans cette page
Téléchargez ce fichier, ouvrez-le dans VSCode, et complétez le code JavaScript à l'intérieur des balises <script>
Déposer le fichier exercices-js-async.html complété dans Classroom
recupererUtilisateur pour qu'elle simule un appel API qui prend 2 secondes.
Utilisez setTimeout pour créer ce délai, puis appelez le callback avec les données de l'utilisateur.
function recupererUtilisateur(id, callback) {
console.log("Recherche de l'utilisateur " + id + "...");
// TODO: Utilisez setTimeout pour simuler un délai de 2000ms
// puis appelez le callback avec les données de l'utilisateur
const utilisateur = {
id: id,
nom: "Alami",
prenom: "Fatima",
ville: "Casablanca"
};
// Votre code ici
}
function recupererUtilisateurAvecErreur(id, callback) {
setTimeout(() => {
// TODO: Si id <= 0, appelez callback(new Error("ID invalide"))
// Sinon, appelez callback(null, utilisateur)
const utilisateur = {
id: id,
nom: "Bennani",
prenom: "Mohammed",
email: "m.bennani@example.ma"
};
// Votre code ici
}, 1000);
}
function recupererUtilisateurAPI(userId, callback) {
const xhr = new XMLHttpRequest();
// TODO: Configurez et envoyez la requête
// 1. xhr.open('GET', url, true)
// 2. xhr.onreadystatechange = function() { ... }
// 3. Vérifiez readyState === 4 et status === 200
// 4. Parsez la réponse avec JSON.parse()
// 5. xhr.send()
console.log("Envoi de la requête pour l'utilisateur " + userId);
// Votre code ici
}
recupererUtilisateur, recupererPosts et recupererCommentaires
sont déjà définies. Vous devez juste les appeler en cascade.
// Fonctions déjà définies (ne pas modifier)
function recupererUtilisateur(id, callback) {
setTimeout(() => {
callback({
id: id,
nom: "El Idrissi",
prenom: "Amina",
ville: "Rabat"
});
}, 1000);
}
function recupererPosts(userId, callback) {
setTimeout(() => {
callback([
{ id: 1, titre: "Introduction à Node.js", userId: userId },
{ id: 2, titre: "Les Promises en JavaScript", userId: userId }
]);
}, 1000);
}
function recupererCommentaires(postId, callback) {
setTimeout(() => {
callback([
{ id: 1, texte: "Excellent article!", auteur: "Khadija" },
{ id: 2, texte: "Très instructif", auteur: "Hassan" }
]);
}, 1000);
}
function demonstrationCallbackHell() {
console.log("Début de la récupération des données...");
// TODO: Appelez les fonctions en cascade
// Attention à l'indentation qui va créer la "pyramide de l'enfer"
// Votre code ici
}
fetch(url) qui retourne une Promiseresponse.okresponse.json().catch()function recupererUtilisateurAvecFetch(userId) {
// TODO: Utilisez fetch() pour récupérer les données
// URL: https://jsonplaceholder.typicode.com/users/{userId}
// return fetch(...)
// .then(response => ...)
// .then(data => ...)
// Votre code ici
}
.then() pour obtenir le même résultat mais avec un code plus lisible.
// Versions Promise des fonctions (déjà définies)
function recupererUtilisateurPromise(id) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
id: id,
nom: "Tazi",
prenom: "Omar",
profession: "Ingénieur"
});
}, 1000);
});
}
function recupererPostsPromise(userId) {
return new Promise((resolve) => {
setTimeout(() => {
resolve([
{ id: 1, titre: "Les bases de MongoDB", userId },
{ id: 2, titre: "Redis pour les débutants", userId }
]);
}, 1000);
});
}
function recupererCommentairesPromise(postId) {
return new Promise((resolve) => {
setTimeout(() => {
resolve([
{ id: 1, texte: "Super article!", auteur: "Youssef" },
{ id: 2, texte: "Merci pour le partage", auteur: "Salma" }
]);
}, 1000);
});
}
function demonstrationPromiseChain() {
console.log("Début avec les Promesses...");
// TODO: Chaînez les promesses avec .then()
// recupererUtilisateurPromise(1)
// .then(utilisateur => { ... })
// .then(...)
// .catch(erreur => { ... })
// Votre code ici
}
Promise.all pour récupérer plusieurs profils d'utilisateurs simultanément.
Comparez le temps d'exécution avec une approche séquentielle.
function recupererProfil(userId) {
return new Promise((resolve) => {
const delai = Math.random() * 2000 + 500; // Entre 500ms et 2500ms
setTimeout(() => {
const noms = ["Zahiri", "Mansouri", "Berrada", "Alaoui", "Benjelloun"];
const prenoms = ["Nadia", "Leila", "Karim", "Sofia", "Ahmed"];
resolve({
id: userId,
nom: noms[userId - 1],
prenom: prenoms[userId - 1],
delai: delai
});
}, delai);
});
}
function demonstrationPromiseAll() {
// TODO: Implémentez deux versions :
// Version 1 : Séquentielle (mauvaise performance)
console.log("Version séquentielle :");
console.time("Durée séquentielle");
// Récupérez les profils 1, 2, 3 l'un après l'autre
// Version 2 : Parallèle avec Promise.all (bonne performance)
console.log("\nVersion parallèle :");
console.time("Durée parallèle");
// Récupérez les profils 1, 2, 3 simultanément
// Votre code ici
}
await pour attendre chaque opération et try/catch pour gérer les erreurs.
// Fonction utilitaire (déjà définie)
function obtenirDonnees(type, id) {
const donnees = {
utilisateur: {
id: 1,
nom: "Rachidi",
prenom: "Amal",
role: "Chef de projet"
},
projet: {
id: 1,
nom: "Migration Cloud",
status: "En cours",
progression: 75
},
taches: [
{ id: 1, titre: "Configuration serveurs", fait: true },
{ id: 2, titre: "Migration base de données", fait: true },
{ id: 3, titre: "Tests de performance", fait: false },
{ id: 4, titre: "Documentation", fait: false }
]
};
return new Promise((resolve, reject) => {
setTimeout(() => {
if (donnees[type]) {
resolve(donnees[type]);
} else {
reject(new Error("Type de données inconnu"));
}
}, 800);
});
}
// TODO: Créez la fonction async
async function afficherTableauDeBord() {
console.log("Chargement du tableau de bord...");
try {
// TODO: Utilisez await pour récupérer :
// 1. L'utilisateur
// 2. Le projet
// 3. Les tâches
// Puis affichez un résumé formaté
// Votre code ici
} catch (erreur) {
console.error("Erreur lors du chargement:", erreur.message);
}
}
async function fetchAvecGestionErreur(url) {
try {
// TODO: Implémentez la logique complète
// 1. Faire la requête avec fetch
// 2. Vérifier response.ok
// 3. Parser le JSON
// 4. Gérer chaque type d'erreur différemment
// Votre code ici
} catch (erreur) {
// TODO: Distinguer les types d'erreurs
// TypeError = erreur réseau
// Autres = erreurs HTTP ou JSON
throw erreur;
}
}
// Fonction de test
async function testerGestionErreurs() {
const urls = [
'https://jsonplaceholder.typicode.com/users/1', // OK
'https://jsonplaceholder.typicode.com/users/9999', // 404
'https://api-inexistante-xyz123.com/test' // Erreur réseau
];
for (const url of urls) {
console.log(`\nTest avec : ${url}`);
try {
const donnees = await fetchAvecGestionErreur(url);
console.log('✓ Succès:', donnees);
} catch (erreur) {
console.error('✗ Erreur:', erreur.message);
}
}
}
--
--
--
// Variables globales pour le dashboard
let intervalId = null;
let isRunning = false;
// Simule une API qui retourne des statistiques
async function obtenirStatistiques() {
const delai = Math.random() * 1000 + 200;
const debut = Date.now();
return new Promise((resolve, reject) => {
setTimeout(() => {
// Simule une erreur 10% du temps
if (Math.random() < 0.1) {
reject(new Error("Erreur serveur"));
} else {
resolve({
utilisateursActifs: Math.floor(Math.random() * 100) + 50,
messagesAujourdhui: Math.floor(Math.random() * 1000) + 200,
tempsReponse: Date.now() - debut
});
}
}, delai);
});
}
// TODO: Implémentez la fonction de mise à jour
async function mettreAJourDashboard() {
try {
// TODO:
// 1. Appelez obtenirStatistiques()
// 2. Mettez à jour les éléments DOM
// 3. Gérez les erreurs gracieusement
// Votre code ici
} catch (erreur) {
// TODO: Affichez l'erreur sans crasher l'application
}
}
// TODO: Implémentez la fonction pour démarrer le dashboard
function demarrerDashboard() {
// TODO:
// 1. Vérifiez si déjà en cours
// 2. Lancez une première mise à jour
// 3. Configurez setInterval pour mise à jour automatique
// 4. Mettez à jour l'état des boutons
// Votre code ici
}
// TODO: Implémentez la fonction pour arrêter le dashboard
function arreterDashboard() {
// TODO:
// 1. Arrêtez l'interval
// 2. Réinitialisez les variables
// 3. Mettez à jour l'interface
// Votre code ici
}
// Fonction bonus : rafraîchissement manuel
function rafraichirMaintenant() {
if (isRunning) {
mettreAJourDashboard();
} else {
console.log("Le dashboard doit être démarré d'abord");
}
}