// =================================================================== // Machine à café — version avec callbacks // =================================================================== // --- Configuration des temps de préparation (en millisecondes) --- const TEMPS_SELECTION = 500; const TEMPS_MOUTURE = 700; const TEMPS_CHAUFFAGE = 1000; const TEMPS_PREPARATION = 500; // --- PARTIE 1 : fonctions asynchrones de base (avec callbacks) --- // Ces fonctions simulent des opérations asynchrones (ex: I/O, requête réseau) // en utilisant un callback comme dernier argument. // Convention : le callback est appelé avec (erreur, resultat). /** * Simule la sélection d'un type de café. * @param {string} nomCafe - le nom du café à sélectionner. * @param {function(Error|null, string?)} callback - la fonction à appeler une fois l'opération terminée. */ function selectionnerCafe(nomCafe, callback) { console.log(`1. Sélection du café : ${nomCafe}...`); setTimeout(() => { console.log(` -> Café "${nomCafe}" sélectionné.`); // Le premier argument est pour une erreur potentielle (ici, null). // Le second est le résultat. callback(null, nomCafe); }, TEMPS_SELECTION); } /** * Simule le broyage des grains de café. * @param {string} nomCafe - le nom du café (reçu de l'étape précédente). * @param {function(Error|null, string?)} callback - la fonction de rappel. */ function moudreGrains(nomCafe, callback) { console.log(`2. Broyage des grains pour ${nomCafe}...`); setTimeout(() => { console.log(" -> Grains moulus."); callback(null, 'grains-moulus'); }, TEMPS_MOUTURE); } /** * Simule le chauffage de l'eau. * @param {number} temperature - la température cible. * @param {function(Error|null, string?)} callback - la fonction de rappel. */ function chaufferEau(temperature, callback) { console.log(`3. Chauffage de l'eau à ${temperature}°C...`); setTimeout(() => { console.log(" -> Eau chaude prête."); callback(null, 'eau-chaude'); }, TEMPS_CHAUFFAGE); } /** * Simule la préparation finale du café. * @param {string} typeCafe - le type de café à préparer. * @param {string} grains - l'ingrédient "grains-moulus". * @param {string} eau - l'ingrédient "eau-chaude". * @param {function(Error|null, string?)} callback - la fonction de rappel finale. */ function preparerCafe(typeCafe, grains, eau, callback) { console.log(`4. Préparation du café ${typeCafe}...`); setTimeout(() => { const cafeFinal = `café ${typeCafe} préparé`; console.log(` -> ${cafeFinal.charAt(0).toUpperCase() + cafeFinal.slice(1)}.`); callback(null, cafeFinal); }, TEMPS_PREPARATION); } // --- PARTIE 2 : le "Callback Hell" --- // On imbrique les appels pour garantir l'ordre d'exécution. // Cette structure en "pyramide" est difficile à lire, à débugger et à maintenir. // C'est l'exemple parfait de ce que les Promises et async/await permettent d'éviter. console.log("\n--- Lancement de la préparation (avec Callback Hell) ---"); selectionnerCafe('Expresso', (errSelect, cafeSelectionne) => { // Chaque étape doit vérifier s'il y a eu une erreur à l'étape précédente. if (errSelect) { console.error("Erreur de sélection :", errSelect); return; // Arrête l'exécution en cas d'erreur. } moudreGrains(cafeSelectionne, (errMoudre, grains) => { if (errMoudre) { console.error("Erreur de broyage :", errMoudre); return; } chaufferEau(90, (errChauffe, eau) => { if (errChauffe) { console.error("Erreur de chauffage :", errChauffe); return; } preparerCafe(cafeSelectionne, grains, eau, (errPrepare, cafeFinal) => { if (errPrepare) { console.error("Erreur de préparation :", errPrepare); return; } console.log(`\nSUCCÈS : Votre ${cafeFinal} est servi !`); }); }); }); }); console.log("\nMessage affiché PENDANT que le café se prépare (non-bloquant).");