2 votes

Boucle d'événement et blocage synchrone

Je suis en train de parcourir "JS For Impatient Programmers" et je suis tombé sur le code suivant.
J'essaie de comprendre la nature synchrone et pourquoi Blocking... attend d'être défini après sleep(5000).
Je crois que l'intention du code était que Blocking... apparaisse à l'écran pendant que le blocage se produit, mais ce n'est pas la réponse réelle lorsque je le saisis dans JSFiddle

document.getElementById('block')
  .addEventListener('click', doBlock);

function doBlock(event) {
  setStatus('Blocking...');
  sleep(5000);
  setStatus('Done');
}

function sleep(milliseconds) {
  const start = Date.now();
  while ((Date.now() - start) < milliseconds);
}

function setStatus(status) {
  document.getElementById('statusMessage')
    .textContent = status;
}

Block

Click me!

0voto

Micha Points 46

Puis-je partager mes conclusions avec le code HTML/JS légèrement modifié suivant?

  1. La version 73.0.3683.75 de Chromium (construite pour openSUSE) (64 bits) fonctionne comme prévu.
  2. La version 67b6 de Firefox Developer Edition (64 bits) fonctionne parfois comme prévu.
  3. La version 60.6.1 ESR de Firefox Stable Quantum (64 bits) ne fonctionne toujours pas comme prévu.

Cependant, si vous passez à un délai de const delayBlocking = 50 millisecondes, le message "Blocking..." s'affiche également dans le navigateur Firefox Stable Quantum 60.6.1 ESR.

Mon interprétation est (selon ce que Mark a dit dans un commentaire) que le navigateur doit être donné le temps de mettre à jour le DOM. Le navigateur doit être capable de rendre au moins une image montrant le message d'état "Blocking..." avant d'entrer dans l'état bloqué (ici pendant 5 secondes). Cela peut être fait avec un setTimeout ajusté de manière appropriée comme le montre l'exemple ci-dessous. -- Cordialement, M.

    Document

    Bloquer

    Cliquez ici !

     document.getElementById('block')
             .addEventListener('click', doBlock);

     function doBlock(event) {
         setStatus('Blocking...');

         // Introducing some ...
         const delayBlocking = 0;

         setTimeout(function() {
             sleep(5000);
             setStatus('Terminé');
         }, delayBlocking);
     }

     function sleep(milliseconds) {
         const start = Date.now();
         while ((Date.now() - start) < milliseconds);
     }

     function setStatus(status) {
         document.getElementById('statusMessage')
                 .textContent = status;
     }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X