0

Here I'm trying to update working inside the setTimeout it gets updated but the addEventListener still has its old value.

const button = document.getElementById('button');


var working = true;

button.addEventListener('click', function() {
  const p = document.getElementById('paragraph');

  p.innerText = "Im working on something that you guys can't see";

  setTimeout(() => {
    working = false
  }, 5000);

  while (working) {
    console.log(working) // This one remains true always.
  }

  p.textContent = "Im done";

});
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 1
    The `while` is called immediately after `setTimeout`, it doesn't wait for the timeout to run. If you want a delayed use of `working`, you will need to put that logic inside the timeout, or use async and await a delay. – pilchard Aug 19 '22 at 07:47
  • Also your while never quits. you have an eternal loop which blocks the execution – mplungjan Aug 19 '22 at 07:47
  • 1
    No it does not. The timeout is simply not able to execute. Use setInterval for the console.log too – mplungjan Aug 19 '22 at 07:49
  • Does this answer your question? [What is the JavaScript version of sleep()?](https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep) – pilchard Aug 19 '22 at 07:50
  • This looks like an XY problem. You are asking why *'it doesn't change'* but it looks like you actually want to know how to delay your function by 5 seconds. – pilchard Aug 19 '22 at 07:50
  • This code is for a demo. I want to block the user for 5 seconds to block them from doing anything. I can achieve the thing that I want by using for loop for few thousand iterations. Since it's a demo it has finite time then listeners can understand my thing easily. Otherwise, I need to wait for the loop to finish. – Mohamed Khan Aug 19 '22 at 07:54
  • @pilchard Yeah, I actually wanted to change after x secs and in the meantime, I want to block the browser from interacting. Reason I can't achieve this because of the variable doesn't change – Mohamed Khan Aug 19 '22 at 08:08
  • Then just mark a timestamp and check it against `now` in the `while` – pilchard Aug 19 '22 at 08:20

1 Answers1

1

The timeout is simply not able to execute due to the while hogging the browser.

Use setInterval for the console.log to see it

const button = document.getElementById('button');
const p = document.getElementById('paragraph');

let working = true;
button.addEventListener('click', function() {
  p.innerText = "I'm working on something that you guys can't see";
  setTimeout(() => {
    working = false
  }, 5000);
  let tId = setInterval(() => {
    console.log(working)
    if (!working) {
      p.textContent = "I'm done";
      clearInterval(tId)
    }   
  },100);  
});
<button id="button">Click</button>
<p id="paragraph"></p>

To hog on purpose for a time, test in the hogging loop

const button = document.getElementById('button');
const p = document.getElementById('paragraph');

button.addEventListener('click', function() {
  p.textContent = "I'm working on something that you guys can't see";
  setTimeout(() => {
    let endTime = new Date()
    endTime.setSeconds(endTime.getSeconds() + 5)

    while (true) {
      let now = new Date()
      if (now.getTime() - endTime.getTime() >= 5000) {
        p.textContent = "I'm done";
        break;
      }
    }
  }, 10)
});
<button id="button">Click</button>
<p id="paragraph"></p>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • I actually want to hogg the browser purposely for a demo. That's why I want it for 5 secs. Is there a way to achieve this? I need a while to hogg the browser. But after a definite time, I want to stop that blocking. My demo is with this library https://partytown.builder.io/ – Mohamed Khan Aug 19 '22 at 08:05
  • Have a look at my update – mplungjan Aug 19 '22 at 08:37
  • You cannot write to screen or console while the loop is running – mplungjan Aug 19 '22 at 08:41