1

I have a chess program that searches moves using a recursive alphaBeta algorithm (and some layers on top of that). I want to stop searching after 10 seconds (but I try with 1 second while making it work), so I use setTimeout to set a global flag.

  let timeOut = false;
  let i = 0;

  setTimeout(() => {
    timeOut = true;
    console.log('timeout');
    console.log('timeout');
    console.log('timeout');
    console.log('timeout');
  }, 1000);

  while (i < 1000 && timeOut === false) {
    score = mtdf(pos, i, score)
    console.log('depth:' + i + ', size: ' + tp.size());
    i++;
  }

This sure runs in the browser so I know the console.log statements should be printed in the browser but they aren't. The callback isn't called. Help please.

Edit: Added timeOut variable initialisation to make it more clear. Also, sorry, forgot to add i initialization (not that these declarations are even relevant to the question, since the problem is that setTimeout callback isn't even being executed...)

2
  • Can you see any errors in the console? Commented Aug 8, 2018 at 7:40
  • No, I only see all the other stuff I console.log, so I know console.log works. Like depth:1, size: 21 Commented Aug 8, 2018 at 7:51

3 Answers 3

3

setTimeout will run the function you pass to it:

  • After the specified time has passed
  • After the minimum time for a timeout has passed
  • When the event loop isn't busy doing something else

… whichever is the latest.

You can't use a timeout to interrupt your while loop. The JavaScript engine is too busy running the while loop to check to see if there are any functions waiting to run on the timeout queue.

Your function will be called after the loop has finished when the JS engine is no longer busy.


Don't try to interrupt your loop from the outside.

Before you enter the while loop, record the current time.

Each time you go around the loop, compare the current time with the recorded time.

If the difference is greater than the period you want to allow the loop to run from, exit the loop

Sign up to request clarification or add additional context in comments.

1 Comment

This is correct I think. This question confirms it: stackoverflow.com/questions/14863022/…
1

Javascript is single threaded meaning that execution of "asynchronous" statements like setTimeout, setInterval, and XMLHttpRequest get queued on a single thread. If something blocks the thread (like your heavy while() loop) async statements get delayed.

See here for more elaborate answer

To make your code work, I suggest looking at the timestamp

var t0 = new Date().getTime(), t1 = t0;
while(true)
{
    // do stuff here
    t1 = new Date().getTime();
    if (t1 % 100 === 0) console.log(t1); // [debug ]print something every 100ms
    if (t1 - t0 > 1000) break; // kill the loop after one second

}

Comments

-1

setTimeout is asynchronous meaning the program won't wait for the setTimeout to finish and the code will continue executing.

You need to use Promise to wait for the setTimout to finish so your code will behave properly.

Also, the problem of your code also lies in the variable declarations, you didn't declare the i and timeOut variables.

let timeOut = false;

new Promise((resolve) => {

  setTimeout(() => {
    timeOut = true;
    console.log('timeout');
    console.log('timeout');
    console.log('timeout');
    console.log('timeout');
    resolve();
  }, 1000);

}).then(() => {

  let i = 0;
  while (i < 1000 && timeOut === false) {
    score = mtdf(pos, i, score)
    console.log('depth:' + i + ', size: ' + tp.size());
    i++;
  }

});

5 Comments

You've misunderstood the question. The OP is trying to stop the while loop from running for more than a second. They aren't trying to delay its start by a second.
Yeah, I got that. So I already mentioned at the last paragraph that the problem lies in the variables.
"Yeah, I got that" — So what is that promise stuff all about then.
because he uses the timeOut in his loop while the timeOut variable assignment is used inside the setTimeout. His code isn't semantically correct. What's the condition timeOut === false for when it will always be false at the end? better just remove it from the condition. Unless, there's something he wants to do with the timeOut variable inside his loop that we don't know thus the reason why he should wrap it with a promise.
They want the loop to start. Then they wants the timeout to run, setting timeOut to false. Then they want the loop to stop because timeOut is false. That can't happen at all, and delaying the start of the loop until the timeout function has been executed and set timeOut to false won't achieve it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.