0

此代码使 chrome 崩溃:

 var ms = 1000;

 function wait(ms) {

     function _done() {
         done = true;
         alert('timer: ' + timer + ', done: ' + done);
         clearTimeout(timer);
     }

     var done = false;
     var timer;
     alert('starting timer');
     while (!done) {
         timer = setTimeout(_done, ms);
     }
     alert('wait done');
 }

为什么?我怎样才能做到这一点?

4

3 回答 3

0

当您在循环内设置计时器变量时,循环不会在循环继续之前等待超时执行。

因此,每次循环发生时您都会覆盖超时,并且代码将永远不会被执行,因为您的 while 循环运行代码的时间不会超过一秒。

看到这里有一个类似的问题:等到一个条件为真?

您的代码将基本上更改为以下内容:

var ms = 1000;
var done = false;
var timer;

function _done() {
    done = true;
    alert('timer: ' + timer + ', done: ' + done);
    clearTimeout(timer);
    wait(ms);
}

function wait(ms) {
    if(!done) {        
        alert('starting timer');
        timer = setTimeout(_done, ms);
    } else {
        //Is Done...
    }
}

一旦你调用等待函数,它会检查done变量是否为真,如果不是,它会调用_done函数将其设置为真。然后该_done函数将重新调用等待函数以再次执行条件。

于 2013-10-02T15:10:44.713 回答
0

这里有很多基本问题。

首先,我假设在您的代码中未描述的某个地方,您实际上是wait通过传递它来调用该函数ms

看起来您想要变量done并且timer可以在您的函数中访问_done。为确保这一点,您应该在定义函数之前初始化变量。

setTimeout是异步的。Javascript 是单线程的,除非您不遗余力地启动其他线程(网络工作者)。setTimeout不会冻结处理ms一段时间。它添加了一个事件,如果没有其他内容正在执行,该事件将运行。因为它没有阻塞,所以您的 while 循环将再次循环以创建另一个超时,以及另一个……无限期。由于其单线程性质,许多超时都不会中断 while 循环。它更像是 Windows 消息队列。由于_done不会中断并设置done为 true,因此它将不断产生越来越多的超时,直到不可避免的崩溃。

如果您想将代码执行延迟一定的时间,setTimeout只要没有其他内容正在执行,您将在等待之后开始执行。

function _done() {
  alert('done!');
}

setTimeout(_done, 1000);

另请注意,我认为您不必clearTimeout为已经超时的超时。它仅用于防止在超时之前发生超时。这意味着十有八九可以忽略setTimeout的返回值。

于 2013-10-02T15:17:07.340 回答
-1

您缺少以下行

timer = setTimeout(_done(), ms);

JSFIDDLE

于 2013-10-02T15:07:28.890 回答