javascript setInterval未按时运行

javascript setInterval未按时运行,javascript,jquery,Javascript,Jquery,我写了一个计时器方法,它不能正常工作。它应该在窗体上显示经过的时间,但它是按2或3秒计数,而不是每秒一次。什么会导致这种行为?我如何修复它 我的代码: 函数startTimer(){ 分钟,秒; setInterval(函数(){ 如果(!i暂停){ 分钟=parseInt(计时器/60,10); 秒=parseInt(计时器%60,10); 分钟=分钟

我写了一个计时器方法,它不能正常工作。它应该在窗体上显示经过的时间,但它是按2或3秒计数,而不是每秒一次。什么会导致这种行为?我如何修复它

我的代码:

函数startTimer(){
分钟,秒;
setInterval(函数(){
如果(!i暂停){
分钟=parseInt(计时器/60,10);
秒=parseInt(计时器%60,10);
分钟=分钟<10?“0”+分钟:分钟;
秒=秒<10?“0”+秒:秒;
$('#TimeLabel').text(“格式时间:“+minutes+”:“+seconds”);
++定时器;
}
}, 1000);

}
我刚刚使用了console中的代码,发现它在那里工作正常,代码是:

  var timer =1;
  var minutes, seconds;

  setInterval(function () {

  minutes = parseInt(timer / 60, 10);
  seconds = parseInt(timer % 60, 10);

  minutes = minutes < 10 ? "0" + minutes : minutes;
  seconds = seconds < 10 ? "0" + seconds : seconds;

  console.log("Form Time: " + minutes + ":" + seconds);

  ++timer;
  }, 1000);
var定时器=1;
分钟,秒;
setInterval(函数(){
分钟=parseInt(计时器/60,10);
秒=parseInt(计时器%60,10);
分钟=分钟<10?“0”+分钟:分钟;
秒=秒<10?“0”+秒:秒;
日志(“格式时间:“+minutes+”:“+seconds”);
++定时器;
}, 1000);

因此,可能有一些东西会增加计时器的值,或者确保函数startTimer只调用一次。

这取决于javascript的异步性质以及它在单个线程上运行的事实

网络上有很多文章解释了事件循环的工作原理,因此,我认为这里没有必要对此进行解释

您只需记住:
setTimeout
setInterval
或其他类似指令将在
延迟时间
作为参数传递后的第一个可用时间执行

所以,
window.setTimeout(function(){console.log('Hello World');},1000)并不意味着将在1000毫秒(1秒)后执行

它基本上意味着等待100ms,当事件循环空闲时,调用作为参数传递的回调


问题可能与未声明所有变量有关。当我在控制台中运行此版本时,它工作正常:

函数startTimer(){
var分钟,秒,isPaused=false,计时器=1;
setInterval(函数(){
如果(!i暂停){
分钟=parseInt(计时器/60,10);
秒=parseInt(计时器%60,10);
分钟=分钟<10?“0”+分钟:分钟;
秒=秒<10?“0”+秒:秒;
日志(“格式时间:“+minutes+”:“+seconds”);
定时器++;
}
}, 1000);
}

startTimer()下面是我想到的一个例子。它使用时间,因此不依赖于设置间隔的准确性。希望这有帮助

function startTimer(){
        var minutes,
            seconds;

        var startTime = new Date;

        setInterval(function(){

            var currentTime = new Date;
            seconds = currentTime.getSeconds() - startTime.getSeconds();

            if(seconds < 0){
                seconds += 60;
            }else if(seconds === 0){
                minutes = currentTime.getMinutes() - startTime.getMinutes();
            }

            console.log(minutes + ':' + seconds);

        }, 100);
}
startTimer();
函数startTimer(){
五分钟,
秒;
var startTime=新日期;
setInterval(函数(){
var currentTime=新日期;
秒=currentTime.getSeconds()-startTime.getSeconds();
如果(秒<0){
秒+=60;
}否则如果(秒===0){
分钟数=currentTime.getMinutes()-startTime.getMinutes();
}
日志(分钟+':'+秒);
}, 100);
}
startTimer();

setInterval
(和
setTimeout
)不保证以任何方式准确。它们只需等待您指定的最短超时时间,并且可以在这之后的任何时间运行。如果该选项卡不处于活动状态,这一点最为明显——在这种情况下,浏览器通常会对其进行严重限制。我没有意识到这一点。我想我需要写一个新的方法,从当前时间中减去,然后用这种方法计算经过的时间。谢谢,另一方面,它们不应该是几秒钟,通常只是几毫秒。我认为,从快速查看代码来看,问题在于如何增加一个数字,然后将其除以以获得秒数等。你不断地在
setTimeout
中合成小错误,直到它变得越来越多,最终是秒数。尽管@JamesThorpe所说的毫无疑问是正确的,当你的网页不在后台时,你的网页必须非常慢才能将1秒的间隔分组在一起。如果你没有看到-@SundarSingh在下面对他的答案的评论中提出了一个有效的观点-你是否肯定
startTimer
只被调用一次?希望你只运行一次startTimer这里的评论可能比你的答案有效得多——如果真的有人打了三次电话,这将解释这种行为。@JamesThorpe我只是在学习如何回答问题,因为我是新来的:)我们都是新来的!这里的问题是,“确保只调用一次”与其说是一个正确的答案,不如说是一个评论,但因为你还没有50个代表,所以你不能在问题本身下做出评论。继续——只需对一些答案进行几次投票,就可以获得“评论无处不在”的特权:)谢谢,这正是我所需要的。