非常不幸的一点是,人们似乎常常将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. maven项目在打war包时出现非法字符: '\ufeff' 解决方案

    问题描述: 开发工具MyEclipse 的总体开发环境,编码格式总体设置为UTF-8,在将web项目打包的时候出现:非法字符:'\ufeff" 错误. 解决方案: 利用notePad++打开 ...

  2. python基础语法学习常见小问题

    说明:我是最近觉得python在完成很多工作中方便使用而且功能强大,想突击学习一下.用的是廖雪峰老师的教程,学习python3.X.这里是廖雪峰老师的网站链接: http://www.liaoxuef ...

  3. C#遍历指定文件夹中的所有文件

    DirectoryInfo TheFolder=new DirectoryInfo(folderFullName);//遍历文件夹foreach(DirectoryInfo NextFolder in ...

  4. Crashlytics功能集成

    总共分三步: 1. 将Crashlytics.framework和Fabric.framework拷贝到工程中: 2.配置工程的info.plist文件,如下: APIKey和Build secret ...

  5. Qt QSortFilterProxyModel示例代码, 使用方法

    1. QSortFilterProxyModel不能单独使用,它只是一个"代理",真正的数据需要另外的一个model提供,而且它是用来排序和过滤的. 2. 实现代码 #ifndef ...

  6. matplotlib中在for中画出多张图

    import matplotlib.pyplot as plt import numpy as np fig, axes = plt.subplots(2, 2) def showim(): for ...

  7. C/C++输入数组

    ; printf("please enter the number:\n"); scanf("%d",&n); int *number=new int[ ...

  8. .net core web发布到CentOS汇总

    直到今天我的博客终于可以见世人了,中间懒了很长一段时间,什么也没干,也没怎么学习,前段时间也是各种折腾,无心学习.本篇主要汇总下从一开始到现在遇到的问题汇总,作为学习笔记.我的博客就是我的学习笔记,因 ...

  9. Android环境配好的标志

    Window —> preference —> android

  10. Mybatis 接口方式对数据的增删改查 一对一关联查询

    数据库中有两个表 student 和studentInfo student表中的字段和数据 studentInfo表中的字段 ok数据库说完了,开始建立一个项目,对数据库中的数据进行操作吧 新建jav ...