Javascript setTimeout的超时时间较短,而超时时间较长

Javascript setTimeout的超时时间较短,而超时时间较长,javascript,angularjs,timer,timeout,Javascript,Angularjs,Timer,Timeout,我试图讨论这是否是一种在Javascript中处理计时器的好方法。我使用的是Angular,但其概念与使用setTimeout而不是$timeoutAngular提供的函数相同 旧方法: $scope.timer=$scope.doTiming(); $scope.timeRemaining=30; //30 second timer; $scope.doTiming=function(){ return $timeout(function(){ $scope.timeR

我试图讨论这是否是一种在Javascript中处理计时器的好方法。我使用的是Angular,但其概念与使用
setTimeout
而不是
$timeout
Angular提供的函数相同

旧方法:

$scope.timer=$scope.doTiming();
$scope.timeRemaining=30; //30 second timer;
$scope.doTiming=function(){
    return $timeout(function(){
        $scope.timeRemaining=$scope.timeRemaining-1;
        if($scope.timeRemaining<=0){
            $scope.disabledEntry=true;
            $scope.submitData();
        }else{
            $scope.timer=$scope.doTiming();
        }
    },1000);
};
30计时器上经过的时间:
30.002秒

主要的区别是,旧的方法每秒循环一次,并计时。新方法不断快速循环,从一开始就根据时间的变化来测量时间,因此它有可能更精确。我想知道这是否合理?这种类型的即时循环会导致旧计算机出现问题吗?我是否应该使用新的方式,用100而不是1的计时器?想法

编辑


这种新方法比我更可取,因为它会导致超时时间变慢:

在我看来,你应该尽可能多地“超时”,但要尽可能少。换句话说,如果您需要每秒更新一次计时器,请每秒触发一次超时。没有人会注意到计时器更新延迟50毫秒(也没有人会在意),因此我认为不值得用额外的JavaScript周期来打扰浏览器,例如。最好花点时间更新一些动画


我想不出有什么理由不适用于增量时间方法。最坏的情况是,一个标签在触发一秒钟超时后立即转到后台。当用户返回到选项卡时,大约需要一秒钟的时间,直到计时器刷新,在这段时间内,用户仍然可以看到他使选项卡处于非活动状态时的计时器值。如果这对于您的用例来说是可以接受的,那么我就不必担心增加间隔:)

您能详细说明为什么不简单地使用setTimeout/$timeout(…,30000)作为开始吗?我还没有掌握您要实现的目标的概念。我需要显示一个计时器,从而更新时钟(
$scope.timeRemaining
)然后调用一个函数,当它完成时,考虑使用-需要支持那些该死的IE。s@TimWithers:您可以使用requestanimationframe和setTimeout作为没有它的浏览器的回退:)
var startTime=new Date().getTime, delta; //new: get current time
$scope.timeRemaining=30;
$scope.timer=$scope.doTiming();
$scope.doTiming=function(){
    return $timeout(function(){
        delta=(new Date().getTime())-startTime; //new: get delta from start time
        $scope.timeRemaining=$scope.timeRemaining-(delta/1000); //new: subtract by delta
        if($scope.timeRemaining<=0){
            $scope.disabledEntry=true;
            $scope.submitData();
        }else{
            $scope.timer=$scope.doTiming();
        }
    },1);
};