Reputation: 725
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...)
Upvotes: 1
Views: 675
Reputation: 4180
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
}
Upvotes: 1
Reputation: 3719
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++;
}
});
Upvotes: -1
Reputation: 943230
setTimeout
will run the function you pass to it:
… 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
Upvotes: 3