您的位置:首页 > Web前端 > AngularJS

angular1.x---angular中清除定时器$interval,解决重复计算问题

2017-04-06 23:18 309 查看
用angular1.x版本做定时器的时候,需要用到内置对象
'$interval'
,用到window原生的setInterval的时候不能及时更新数据,但是’$interval’定义的定时器却不像setInterval那么容易清除。

———————————————————————-

查看源码,angular提供有例子进行说明定时器的清除:

<script>
*     angular.module('intervalExample', [])
*       .controller('ExampleController', ['$scope', '$interval',
*         function($scope, $interval) {
*           $scope.format = 'M/d/yy h:mm:ss a';
*           $scope.blood_1 = 100;
*           $scope.blood_2 = 120;
*
*           var stop;
*           $scope.fight = function() {
*             // Don't start a new fight if we are already fighting
*             if ( angular.isDefined(stop) ) return;
*
*             stop = $interval(function() {
*               if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
*                 $scope.blood_1 = $scope.blood_1 - 3;
*                 $scope.blood_2 = $scope.blood_2 - 4;
*               } else {
*                 $scope.stopFight();
*               }
*             }, 100);
*           };
*
*           $scope.stopFight = function() {
*             if (angular.isDefined(stop)) {
*               $interval.cancel(stop);
*               stop = undefined;
*             }
*           };
*
*           $scope.resetFight = function() {
*             $scope.blood_1 = 100;
*             $scope.blood_2 = 120;
*           };
*
*           $scope.$on('$destroy', function() {
*             // Make sure that the interval is destroyed too
*             $scope.stopFight();
*           });
*         }])
*       // Register the 'myCurrentTime' directive factory method.
*       // We inject $interval and dateFilter service since the factory method is DI.
*       .directive('myCurrentTime', ['$interval', 'dateFilter',
*         function($interval, dateFilter) {
*           // return the directive link function. (compile function not needed)
*           return function(scope, element, attrs) {
*             var format,  // date format
*                 stopTime; // so that we can cancel the time updates
*
*             // used to update the UI
*             function updateTime() {
*               element.text(dateFilter(new Date(), format));
*             }
*
*             // watch the expression, and update the UI on change.
*             scope.$watch(attrs.myCurrentTime, function(value) {
*               format = value;
*               updateTime();
*             });
*
*             stopTime = $interval(updateTime, 1000);
*
*             // listen on DOM destroy (removal) event, and cancel the next UI update
*             // to prevent updating time after the DOM element was removed.
*             element.on('$destroy', function() {
*               $interval.cancel(stopTime);
*             });
*           }
*         }]);
*   </script>


一大串代码,似乎不太容易,远不止简单的设置timer=null就可以解决的,虽然可以实现,但是今天在公司项目中遇到了问题,无论如何仿照源码都无法解决问题,于是继续寻找并打印$interval源码:

function interval(fn, delay, count, invokeApply) {
var hasParams = arguments.length > 4,
args = hasParams ? sliceArgs(arguments, 4) : [],
setInterval = $window.setInterval,
clearInterval = $window.clearInterval,
iteration = 0,
skipApply = (isDefined(invokeApply) && !invokeApply),
deferred = (skipApply ? $$q : $q).defer(),
promise = deferred.promise;

count = isDefined(count) ? count : 0;

promise.then(null, null, (!hasParams) ? fn : function() {
fn.apply(null, args);
});

promise.$$intervalId = setInterval(function tick() {
deferred.notify(iteration++);

if (count > 0 && iteration >= count) {
deferred.resolve(iteration);
clearInterval(promise.$$intervalId);
delete intervals[promise.$$intervalId];
}

if (!skipApply) $rootScope.$apply();

}, delay);

intervals[promise.$$intervalId] = deferred;

return promise;
}


源码中,$interval定义一个定时器可以传入四个参数(fn, delay, count, invokeApply):
fn://定时器的执行函数
delay://每次函数执行的间隔时间
count://函数fn的执行次数
invokeApply://设置脏值检测


通过count的设置便解决今天项目中,数值无限减小问题,代码如下:

$scope.num=60;
$scope.timer=$interval(function(){
$scope.num--;
},1000,$scope.num);
///在切换控制器的时候,清除定时器,减少内存损耗
$scope.$on(
"$destroy",
function() {
$interval.cancel( $scope.timer);
}
);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息