JavaScript之定时器

定时器
JavaScript 提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成。它们向任务队列添加定时任务。
1,setTimeout()
setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。

var timerId = setTimeout(func|code,delay);

setTimeout函数接受两个参数,第一个参数是将要推迟执行的函数名或一段代码,第二个参数是推迟执行的毫秒数(如果省略默认为0)。

setTimeout函数还允许更多的参数,它们将以此传入推迟执行的函数(回调函数)。

setTimeout(function(a,b){
	console.log(a + b);
},1000,1,1);

以上代码,setTimeout共有4个参数,最后两个参数将在1000毫秒之后回调函数执行时,作为回调函数的参数。

如果回调函数是对象的方法,那么setTimeout是的方法内部的this关键字指向全局环境,而不是定义时所在的那个对象。

2,setInterval()
setInterval函数的用法与setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行。

var timer = setInterval(function(){
	console.log(2);
},1000);
//每个1000毫秒就会输出一个2,知到窗口关闭

和setTimeout一样,除了前两个参数,可以接受更多的参数传入回调函数。

3,clearTimeout(),clearInterval()

setTimeout和setInterval函数都返回一个整数值,表示计数器编号。将改正数传入clearTimeout和clearInterval函数,就可以取消对应的定时器。
使用如下:

var timer1 = setTimeout(f,1000);
var timer2 = setInterval(f,1000);

clearTimeout(timer1);
clearInterval(timer2);

4,实例:debounce函数(防抖动)
如果,我们不希望回调函数被频繁调用。比如,用户填入网页输入框的内容,希望通过Ajax方法返回服务器,JQuery的写法如下:

$('textarea').on('keydown',ajaxAction);

这样写有一个很大的缺点,就是如果用户连续击键,就会触发keydown事件,造成大量的Ajax通信。这是不必要的,而且很可能产生性能问题。正确的做法应该是,设置一个门槛值,表示两次Ajax通信的最小间隔时间。如果在间隔时间内,发生的新的keydown事件,则不必触发Ajax通信,并且重新开始计时。如果过了指定时间,没有新的keydown事件,再将数据发送出去。
这种做法叫做debounce(防抖动) 。假定两次Ajax通信的时间间隔不得小于2500毫秒,上面的代码可以改写成下面这样:

$('textarea').on('keydown',debounce(ajaxAction,2500));
function debounce(fn,delay){
	var timer = null;  //声明计时器
	return function(){
		var context = this;
		var args = arguments;
		clearTimeout(timer);
		timer = setTimeout(function(){
			fn.apply(context,args);
		},delay);
	};
};

上面代码中,只要在2500毫秒之内,用户再次点击,就会取消上一次的定时器,然后再新建一个定时器。这样就保证了回调函数之间的调用间隔,至少是2500毫秒。

5,强行机制
setTimeout和setInterval的运行机制,是将指定的代码移出本轮时间循环,等到下一轮循环,再检查是否到了指定时间。如果到了,就执行对应的代码,如果不到就继续等待。
这意味着,setTimeout和setInterval指定的回调函数,必须等到本轮事件循环的所有同步任务都执行完,才会开始执行。由于前面的任务到底需要多少时间执行完,是不确定的,所以没有办法保证,setTimeout和setInterval指定的任务,一定会按照预定时间执行。

setTimeout(someTask,100);
veryLongTask();

上述代码setTimeout指定100毫秒以后运行一个任务,但是如果后面的veryLongTask函数(同步任务)运行时间非常长,过了100毫秒还无法结束,那么被推迟运行的someTask就只能等着,直到veryLongTask运行结束,才能轮到它执行。

setInterval(function(){
	console.log(2);
},1000);

sleep(3000);

function(ms){
	var start = Date.now();
	while((Date.now() - start) < ms) {
	}
}

上面代码中,setInterval要求每隔1000毫秒,就输出一个2.但是紧接着的sleep语句需要3000毫秒才能完成,那么setInterval就必须推迟到3000毫秒之后才能开始生效。生效后setInterval不会产生累计效应,即不会一下子输出三个2,而是只会输出一个2.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值