定时器到期后重置 setTimeout

Reset setTimeout after timer expires

我有一个正在进行的 while 循环。在while循环中,有一个setTimeout()。我想在定时器到期后重置定时器。换句话说,当定时器到期时,它应该做一些指定的动作,然后重新启动定时器。

例如,在下面的代码中,%%--Hi--%% 应该在 5 秒内只打印一次。但是,5秒后,连续打印%%--Hi--%%。我试过 clearTimeout 但看起来 clearTimeout 只能在计时器到期之前停止计时器。

while(){
    var timeoutHandle = setTimeout(function() {
                        console.log("%%--Hi--%%");
                        clearTimeout(timeoutHandle);
                        }, 
                        5000); //5 sec
}

请帮忙!谢谢!

试试这个代码:

logFun();

function logFun() {
    console.log("%%--Hi--%%");
    setTimeout(logFun, 5000);
}

或者,您可以尝试 setInterval:

setInterval(function () {
    console.log("%%--Hi--%%");
}, 5000);

您的问题是 setTimeout 是一个异步函数,因此您的代码不会等待它完成后再循环。要解决这个问题,您必须在之前的计时器中创建新的计时器。

同样,您必须从计时器内部调用您想要执行的任何操作,而不能只在 while 循环中调用它们,因为它们不会等待计时器完成。

function logFun() {
    console.log("%%--Hi--%%");
    // execute actions
    setTimeout(logFun, 5000);
}

这是易布易生对刚刚出现的答案所做的。 (因为没有解释答案所以还在发帖。)

让您失望的不是超时,而是无限的 while 循环。您实际上每秒创建了数千个超时。将超时移到无限循环之外应该可以解决您的问题。

function timedAction() {
    // your timed actions to be invoked every 5 seconds

    setTimeout(timedAction, 5000); // start the next timeout
}

setTimeout(timedAction, 5000); // start the first timeout

while() {
    // your continuously executing actions
}

超时后无需清除。

或者您也可以使用 setInterval,简化您的代码如下:

function timedAction() {
    // your timed actions to be invoked every 5 seconds
}

setInterval(timedAction, 5000); // start the interval

while() {
    // your continuously executing actions
}

setTimeout 方法的行为不像睡眠语句。无论您在 setTimeout 方法中设置的时间间隔如何,您的 while 循环将继续不断迭代。

您应该删除 while 并简单地使用 setInterval()(在 中提到。+1)

var myInterval = setInterval(function () {
    console.log("%%--Hi--%%");
}, 5000);

如果要停止间隔,运行如下:

clearInterval(myInterval);

或者,如果您必须从 while 循环创建 setTimeout(),您可以使用布尔值 (true/false) 锁定它。这不像 yibuyisheng 的回答那么干净,但它也允许您添加尽可能多的逻辑来控制启用和禁用超时。

示例:

window.isTimeoutLocked = false;

while(true) {
   if (!window.isTimeoutLocked) {
     var myFunction = function () {
       console.log("%%--Hi--%%");
       //The timeout has fired. Unlock it for the next one.
       window.isTimeoutLocked = false;
     }
     window.setTimeout(myFunction, 5000);

     //Timeout is queued. Lock this code until the timeout fires.
     window.isTimeoutLocked = true;
   }
}

此外,我怀疑无限 while 循环是否最适合您的上游代码。可能有一个你可以挂钩的回调,比如 requestAnimationFrame 或一些相关事件。