2

I've tried using do-while loops but it doesn't seem to be working properly:

let rep; //this variable tells the loop whether to run or not
let nOfTimesTheLoopRuns = 0;

do {
    nOfTimesTheLoopRuns++;
    console.log(`This loop has run ${nOfTimesTheLoopRuns} time(s).`);

    setTimeout( () => {
        rep = confirm("Repeat?");
    }, 2000); //a delay is set so that the answer can be printed on the console before the code runs again
} while (rep);

The console prints: "This loop has run 1 time(s).", but it doesn't repeat as it should when I press "Ok" in the confirm(); dialog box.

I've also tried this:

let rep = []; //this variable tells the loop whether to run or not
let nOfTimesTheLoopRuns = 0;

do {
    rep.pop();

    nOfTimesTheLoopRuns++;
    console.log(`This loop has run ${nOfTimesTheLoopRuns} time(s).`);

    setTimeout( () => {
        rep.push(confirm("Repeat?"));
    }, 2000); //a delay is set so that the answer can be printed on the console before the code runs again
} while (rep[0]);

In the end, the console prints "This loop has run 1 time(s)." And the value of nOfTimesTheLoopRuns is 1. How can I make it so that it keeps running every time the user presses "Ok" in the confirm(); dialog box?

Laionlel
  • 23
  • 2
  • It's not working as you expect because the `setTimeout` doesn't change the value of `rep` until after the loop tests it. It is not set to anything before the loop and the test fails. Even if it were set to a value it would not be the value set in the `setTimeout` since it runs about 2 seconds after the loop terminates. Reading about [asynchronous JS](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous) may be helpful. Recursion as suggested in the answers works, but you may have other options depending upon your ultimate goal if this was for testing only. – Gary Oct 28 '21 at 18:26

3 Answers3

1

You can do put the code you want to execute each time the user confirms into a function, then check whether rep is true in the setTimeout callback and call the function again if so:

let nOfTimesTheLoopRuns = 0;

function check() {
  nOfTimesTheLoopRuns++;
  console.log(`This loop has run ${nOfTimesTheLoopRuns} time(s).`);
  setTimeout(() => {
    if (confirm("Repeat?")) {
      check()
    }
  }, 2000)
}


check()
Spectric
  • 30,714
  • 6
  • 20
  • 43
0

You can use a function that calls itself if answer is true.

let nOfTimesTheLoopRuns = 0;
function test() {
  if (confirm("Repeat") === true) {
    nOfTimesTheLoopRuns++;
    console.log(`This loop has run ${nOfTimesTheLoopRuns} time(s).`);
    setTimeout(() => test(), 2000);
  }
}
test();
Gabriel
  • 670
  • 1
  • 8
  • 24
  • Thank you so much! I've spent way more time than I should have on this problem and you just solved it! I tested it and it works with my original code, which is awesome. Thank you :D – Laionlel Oct 28 '21 at 19:41
0

This is because the setTimeout would run after the completion of the loop, that's how the javascript handles asynchronous functions. You can better understand this by reading concept of Event loop

What you can do is to put all your code in an interval and clear it when user selects 'cancel'.

var nOfTimesTheLoopRuns = 0;
var myInterval = setInterval(function(){
    nOfTimesTheLoopRuns++;
    console.log(`This loop has run ${nOfTimesTheLoopRuns} time(s).`);
    if(!confirm("Repeat?")){
       clearInterval(myInterval);
    }
}, 3000);
Noor Ul Ain
  • 570
  • 5
  • 9