JavaScript setTimeout运行两次

JavaScript setTimeout Runs Twice

本文关键字:两次 setTimeout 运行 JavaScript      更新时间:2023-09-26

我正试图使一个函数,以精确的间隔开始,以保持稳定的更新率。问题是它似乎在2个通道中执行。日志如下:

timeElapsed=141; lastDraw=1314040922291
timeElapsed=860; lastDraw=1314040923151
timeElapsed=141; lastDraw=1314040923292
timeElapsed=860; lastDraw=1314040924152
timeElapsed=141; lastDraw=1314040924293
timeElapsed=860; lastDraw=1314040925153
timeElapsed=141; lastDraw=1314040925294
timeElapsed=860; lastDraw=1314040926154
timeElapsed=141; lastDraw=1314040926295
timeElapsed=859; lastDraw=1314040927154
timeElapsed=143; lastDraw=1314040927297
timeElapsed=858; lastDraw=1314040928155
timeElapsed=143; lastDraw=1314040928298
timeElapsed=858; lastDraw=1314040929156
timeElapsed=142; lastDraw=1314040929298

首先,我使用

执行函数
drawTimer = setTimeout(function(){ draw() }, 1);

,函数是这样的:

var draw = function(){
    if(!running)
        return;
    var miliseconds = getCurrentMiliseconds();
    var timeElapsed = miliseconds - lastDraw;
    lastDraw = miliseconds;
    console.log("timeElapsed=" + timeElapsed + "; lastDraw=" + lastDraw);
    onDrawListener(timeElapsed);
    if(timeElapsed < timeLapse)
        miliseconds = timeLapse - timeElapsed;
    else
        miliseconds = 1;        
    drawTimer = setTimeout(function(){ draw() }, miliseconds);
}

Chrome和Firefox都是如此。你知道它是由什么引起的吗?和…如何解决这个问题?

注:由于每个人似乎都对running变量感到困惑,这里是:它是一个私有父对象成员,指示该机制是否仍在运行或已停止。它是由其他函数设置的,只是为了确保这个函数在stop()被调用后不会继续工作。

——update——时间间隔设置为1000(每秒1次),并且永远不会再更改。

onDrawListener设置为这个函数:

function(timeElapsed){
        canvas.clear();
        moveSnake();
        if(snake.body[0] == food){
            food = getRandomFreePosition();
            ++snake.body.lenght;
        }

        drawBackground();
        drawFood();
        drawSnake();
    }

来解释它:canvas是一种引擎,它负责回调,键监听,也有一些功能。除此之外,这似乎是不言自明的。它们除了一些int算法和在画布上绘图之外什么也不做。

——figure out——我明白我应该计算当前函数花费的时间,而不是从上一个函数开始。我的旧方法不是在2通道中工作,而是在长-短-长-短-长-…延迟

首先,你不设置运行bool,而且当你进入函数时,立即在drawTimer上做一个on clearartimeout。

clearTimeout(drawTimer);

在这样的循环中,您应该考虑这样写:

 if(timeElapsed >= AMOUNT_OF_TIME) 
{   
 // run code 
}