setTimeout具有更短的超时与更长的超时

时间:2013-10-24 20:16:02

标签: javascript angularjs timer timeout

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

旧方法:

$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.050 seconds

新方法:

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);
};

30计时器已过去的时间:30.002 seconds

主要区别在于旧方法每秒循环,并勾选计时器。新方法可以非常快速地循环,并根据从一开始就改变的时间来测量时间,因此它有可能更加准确。我想知道这是否合理?这种类型的即时循环是否会导致旧计算机出现问题?我是否可以使用100的计时器而不是1的新方式?想法?

修改

由于与超时速度减慢相关的原因,新方式对我来说更为可取:Chrome: timeouts/interval suspended in background tabs?

1 个答案:

答案 0 :(得分:2)

在我看来,你应该根据需要做尽可能多的“超时”,但尽可能少。换句话说,如果您需要每秒更新一个计时器,则每秒触发一次超时。没有人能够注意到定时器更新延迟50ms(也没人会关心),所以我认为不值得用额外的JavaScript循环来打扰浏览器,例如。可能会更好地更新一些动画。

我想不出为什么这也不适用于delta时间方法的原因。最糟糕的情况是,在触发一秒超时后,选项卡会立即进入后台。当用户返回选项卡时,它将花费大约一秒钟直到计时器将刷新,并且在该间隔中,用户仍然会看到计时器值从他使选项卡处于非活动状态时。如果您的用例可以接受,我根本不担心增加间隔:)