setTimeout不调用回调来中断while循环

时间:2018-08-08 07:37:16

标签: javascript settimeout

我有一个国际象棋程序,该程序使用递归alphaBeta算法(及其顶部的某些层)搜索移动。我想在10秒后停止搜索(但是我尝试在使其工作的同时尝试1秒),所以我使用setTimeout设置了全局标志。

  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++;
  }

这肯定在浏览器中运行,所以我知道console.log语句应该在浏览器中打印,但不是。回调不被调用。请帮助。

编辑:添加了timeOut变量初始化,以使其更加清晰。另外,很抱歉,忘记添加i初始化(不是这些声明甚至与问题相关,因为问题是setTimeout回调甚至没有被执行...)

3 个答案:

答案 0 :(得分:2)

setTimeout将运行传递给它的函数:

  • 经过指定时间后
  • 在最短超时时间过去之后
  • 当事件循环不忙于做其他事情时

…以最新为准。

您不能使用超时来中断while循环。 JavaScript引擎忙于运行while循环,无法检查是否有任何函数在等待超时队列。

当JS引擎不再繁忙时,将在循环结束后调用您的函数。


不要试图从外面打断循环。

在进入while循环之前,请记录当前时间。

每次循环时,请将当前时间与记录的时间进行比较。

如果差异大于您要允许循环运行的时间,请退出循环

答案 1 :(得分:1)

Javascript是单线程的,这意味着诸如setTimeout,setInterval和XMLHttpRequest之类的“异步”语句的执行在单个线程上排队。如果某些东西阻塞了线程(例如沉重的while()循环),异步语句就会延迟。

有关详细说明,请参见here

为使您的代码正常工作,建议您查看时间戳记

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

}

答案 2 :(得分:-1)

setTimeoutasynchronous,表示程序将不等待setTimeout完成,并且代码将继续执行。

您需要使用Promise等待setTimout完成,以便您的代码正常运行。

此外,代码的问题还在于变量声明,而您没有声明itimeOut变量。

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++;
  }

});