非常不幸的一点是,人们似乎常常将AngularJS中的$timeOut()函数看做是一个内置的、无须在意的函数。但是,如果你忘记了$timeOut()的回调函数将会造成非常不好的影响,你可能会因此遇到代码莫名其妙的出现问题,或者无端抛出一个错误甚至是一遍一遍的重复对的你的服务器进行$http请求这些诡异的情形。管理好你的$timeOut定时器的小技巧就是在$destory事件中将它们取消。

和javascript中原生的setTimeout()以及setInterval()函数不同,AngularJS中的$timeOut()函数会返回一个promise。和其他的promise一样,你可以绑定$timeOut的resolved和rejected时间。然而更重要的是,你可以通过将这个promise传递给$timeOut.cancel()方法来取消掉潜在的定时器。

在一个AngularJS应用中,这一点非常的重要,因为定时器可以结束执行那些不再与应用状态和用户界面相关的代码。最佳情形中,这些过程都会悄悄的发生;在不好的情况下,它会引起不可预测的行为并导致很差的用户体验。为了让应用顺畅的运行,你应该总是把握好你的$timeOut定时器;你需要在相应的控制器和指令接收到$destory事件时调用$timeOut.cancel()方法。

为了更加清楚的说明这点,下面的这个例子将会有一些DOM元素通过ngSwitch/ngSwitchWhen指令来创建或销毁。注意到当$destory事件被触发时(在这里的例子中是位于指令中),我们将取消当前的定时器:

<!doctype html>
<html ng-app="Demo" ng-controller="DemoController">
<head>
<meta charset="utf-8" />

<title>
Don't Forget To Cancel $timeout Timers In Your $destroy Events In AngularJS
</title>
</head>
<body>

<h1>
Don't Forget To Cancel $timeout Timers In Your $destroy Events In AngularJS
</h1>

<p>
<a href="#" ng-click="toggle()">Toggle Section</a>
</p>

<div ng-switch="section">

<p ng-switch-when="happy" bn-directive>
Oh sweet!
</p>

<p ng-switch-when="sad" bn-directive>
Oh noes!
</p>

</div>

<!-- Load jQuery and AngularJS. -->
<script
type="text/javascript"
src="../../vendor/jquery/jquery-2.0.3.min.js">
</script>
<script
type="text/javascript"
src="../../vendor/angularjs/angular-1.0.7.min.js">
</script>
<script type="text/javascript">

//为我们的demo创建一个应用模块
var app = angular.module( "Demo", [] );

// -------------------------------------------------- //
// -------------------------------------------------- //

// 定义控制器
app.controller(
"DemoController",
function( $scope ) {

$scope.section = "happy";

//在toggle函数中改变section的值,以此在标记中显示/隐藏不同的部分
$scope.toggle = function() {

if ( $scope.section === "happy" ) {

$scope.section = "sad";

} else {

$scope.section = "happy";

}

};

}
);

// -------------------------------------------------- //
// -------------------------------------------------- //

//定义指令
app.directive(
"bnDirective",
function( $timeout ) {

//将用户界面的事件绑定到$scope上
function link( $scope, element, attributes ) {

//当timeout被定义时,它返回一个promise对象
var timer = $timeout(
function() {

console.log( "Timeout executed", Date.now() );

},
2000
);

//将resolve/reject处理函数绑定到timer promise上以确保我们的cancel方法能正常运行
timer.then(
function() {

console.log( "Timer resolved!", Date.now() );

},
function() {

console.log( "Timer rejected!", Date.now() );

}
);

//当DOM元素从页面中被移除时,AngularJS将会在scope中触发$destory事件。这让我们可以有机会来cancel任何潜在的定时器
$scope.$on(
"$destroy",
function( event ) {

$timeout.cancel( timer );

}
);

}
//返回指令的配置
return({
link: link,
scope: false
});

}
);

</script>

</body>
</html>

一般来说,放任$timeOut定时器可能不会有多大的影响。但是最好的做法是将它cancel掉,因为它有可能会造成很差的用户体验(或者想你的服务器发出不必要的请求)。这一点对于控制器和指令来说同样重要。

随机推荐

  1. .NET 中如何判断文件与目录

    FileInfo fileInfo = new FileInfo(pth); if ((fileInfo.Attributes & FileAttributes.Directory) != 0 ...

  2. struts2实现文件的上传和下载实例[转]

    实现原理 Struts 2是通过Commons FileUpload文件上传. Commons FileUpload通过将HTTP的数据保存到临时文件夹,然后Struts使用fileUpload拦截器 ...

  3. ViewPagerAdapter 示例

    package com.ali.fridge.supermarket.module; /**  * Created by xiaomin.wxm on 2016/3/7.  */ import and ...

  4. UOJ222 【NOI2016】区间

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  5. python3与anaconda2共存

    我是先下载了python3,后来因为需要2为了省事就去下载了anaconda2,但发现这里有个很严重的共存问题. 找了一下网上的各种共存问题,发现网上的基本上都是基于一个anaconda然后通过虚拟环 ...

  6. 0.00-050613_zc

    1. ROM bios --> 启动盘第一个扇区(此处内容为boot) 加载到 内存位置0x7C00(31KB) --> 执行权转移(也就相当于跳转) boot程序主要功能:把 软盘/映像 ...

  7. review05

    子类与继承 所有类都是Object的子孙类. 子类继承了父类的成员变量和方法,就好像是在子类中直接定义了一样. 如果子类和父类在同一个包中,子类自然地继承了父类中不是private的成员变量和方法. ...

  8. Python安装升级步骤

    1)安装Pyhton2.7wget http://www.python.org/ftp/python/2.7.5/Python-2.7.5.tar.bz2tar xjvf Python-2.7.5.t ...

  9. 201621123014《Java程序设计》第八周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 答: 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 答: Arr ...

  10. python3 xrange报错

    因为python3取消了xrange这个函数,range就是xrange.