Try   HackMD

JavaScript - Promise

En JavaScript, une Promise est un objet représentant l'achèvement ou l'échec éventuel d'une opération asynchrone.

Les promesses sont un moyen de gérer des opérations asynchrones en JavaScript. Elles sont utilisées pour encapsuler une valeur qui peut être disponible immédiatement ou plus tard. Une promesse peut être dans l'un des trois états suivants : en attente, résolue ou rejetée. Les promesses sont créées à l'aide du constructeur Promise().

Exemple :

 // Tester la valeur 1 ou 42
const test = 2*21;
console.log("etape 1 - Début du script");
// Création de la promesse
const promesse = new Promise((resolve, reject) => {
console.log("étape avant de resoudre la promesse");
// Traitement des instructions qui prendront du temps
setTimeout(() => {
  if (test === 42) {
    console.log(
      "✅ Réponse async: Les conditions sont remplies"
    );
    resolve(test);
  } else {
    console.log(
      "❌ Réponse async: Les conditions ne sont pas remplies"
    );
    reject(test + " Rejet de la promesse");
  }
}, 2000);
});
console.log("promesse:", promesse);
console.log("etape 2 - Après la déclaration de la promesse");
// Execution de la promesse
promesse
.then((value) => {
  console.log("promesse:", promesse);
  console.log("Resolution de la promesse: ", value);

})
.catch((error) => {
  console.log("promesse:", promesse);
  console.error(error);
});
console.log("etape 3 - Après l'execution de la promesse");

☝🏼 Attention, les promesses ne peuvent pas être réutilisées une fois acceptées ou rejetées

Les promesses ont trois états principaux :

  1. Pending (En attente) :
  • Lorsqu'une promesse est créée, elle entre initialement dans l'état "pending". Cela signifie que l'opération asynchrone associée n'est ni terminée ni rejetée, mais est toujours en cours.
  • Dans cet état, une promesse peut passer à l'état "fulfilled" (résolue) ou "rejected" (rejetée), en fonction du résultat de l'opération asynchrone.
  1. Fulfilled (Résolue) :
  • Une promesse passe à l'état "fulfilled" lorsque l'opération asynchrone se termine avec succès.
  • Dans cet état, la promesse a une valeur associée, qui est généralement le résultat de l'opération asynchrone réussie.
  • Une fois qu'une promesse est résolue, son état ne change plus, et elle a une valeur définitive.
  1. Rejected (Rejetée) :
  • Une promesse passe à l'état "rejected" si l'opération asynchrone échoue ou si une erreur se produit pendant son exécution.
  • Dans cet état, la promesse a une raison de rejet, qui explique pourquoi l'opération a échoué.
  • Comme pour une promesse résolue, une promesse rejetée ne change plus d'état après son rejet.

En plus de ces états, les promesses JavaScript fournissent des méthodes pour gérer les résultats de ces opérations asynchrones :

  • .then(onFulfilled, onRejected) :

    • Permet d'attacher des gestionnaires de succès (onFulfilled) et d'erreur (onRejected) à la promesse.
    • onFulfilled est appelé si la promesse est résolue, tandis que onRejected est appelé si la promesse est rejetée.
  • .catch(onRejected) :

    • Permet d'attacher un gestionnaire d'erreur à la promesse.
    • C'est un raccourci pour .then(null, onRejected) et est généralement utilisé pour gérer les erreurs.
  • .finally(onFinally) :

    • Permet d'exécuter un code indépendamment du résultat de la promesse, que celle-ci soit résolue ou rejetée.
    • Utile pour exécuter du nettoyage ou des tâches de finalisation.

Les promesses permettent de gérer les opérations asynchrones de manière plus lisible et structurée, évitant ainsi les problèmes courants associés aux callbacks, tels que le "callback hell". De plus, les promesses sont au cœur de la syntaxe async/await en JavaScript moderne, offrant une approche encore plus élégante pour gérer l'asynchronie.

Obtenir un comportement synchrone

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>setTime & setInterval</title>
    <style>
        * {
            box-sizing: border-box;
        }

        body {
            font-family: Arial, Helvetica, sans-serif;
        }
    </style>
</head>

<body>
    <main>
        <h1></h1>
        <button id="btn-start" class="btn btn-start" type="button">Démarer</button>
        <div id="quiz-container"></div>

    </main>
    <script>

        console.log("quiz.js loaded");

        const h1 = document.querySelector('h1').innerText = document.title;
        const quizContainer = document.querySelector("#quiz-container");
        const btn = document.querySelector("#btn-start");

        let i = 0;
        const intervalDuration = 1000;
        const timeLimit = 3;
        let intervalID = null;

        btn.addEventListener("click", repeatQuiz); // Démarrer le premier intervalle

        // Méthode 1
        // Fonction qui retourne une promesse résolue après 5 secondes
        const pause1 = () => {
            return new Promise(resolve => {
                setTimeout(() => {
                    resolve("5s !");
                }, 5000);
            });
        };

        // Méthode 2
        // Fonction qui retourne une promesse résolue après 5 secondes
        const pause2 = async () => {
            await new Promise(resolve => setTimeout(resolve, 5000));
        };
        async function repeatQuiz() {
            if (intervalID) { clearInterval(intervalID) };
            quizContainer.innerHTML = "";
            const p = document.createElement("p");
            quizContainer.appendChild(p);
            i = 0;
            intervalID = setInterval(async () => {
                console.log(i + " sec");
                p.innerText = i === 1 ? i + " seconde" : i + " secondes";
                i++;
                if (i === timeLimit) {
                    clearInterval(intervalID);
                    console.log("Temps écoulé !");
                    p.innerText = "Temps écoulé !";
                    await pause2();
                    // Coisir méthode 1 ou 2
                    repeatQuiz(); // Redémarrer l'intervalle
                }
            }, intervalDuration);
        }

    </script>
</body>

</html>

Il faut crée une nouvelle promesse à l'aide d'une fonction. Cela garantie qu'une nouvelle promesse sera crée et exécutée à chaque appel de la fonction.