繁体   English   中英

javascript settimeout永不触发功能,导致Chrome崩溃

[英]javascript settimeout never fires function and crashes chrome

这段代码会使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');
 }

为什么? 我该如何正确处理?

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

因此,每次循环发生时,您都将覆盖超时,并且代码将永远不会执行,因为您的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...
    }
}

一旦调用了wait函数,它将检查done变量是否为true,否则,它将调用_done函数将其设置为true。 然后_done函数将重新调用wait函数以再次执行条件。

这里有很多基本问题。

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

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

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

如果您希望将代码执行延迟一定的时间,则只需设置一次setTimeout ,只要没有其他任何执行,则将在等待之后开始执行。

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

setTimeout(_done, 1000);

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

您缺少以下行

timer = setTimeout(_done(), ms);

JSFIDDLE

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM