【前端实例】JavaScript定时器的运用

目录

一、什么是定时器

二、setTimeout和setInterval例子

三、JS定时器的工作原理

参考来源:http://caibaojian.com/javascript-timer.html


一、什么是定时器

JS提供了一些原生方法来实现延时去执行某一段代码,下面来简单介绍一下

setTimeout: 设置一个定时器,在定时器到期后执行一次函数或代码段

var timeoutId = window.setTimeout(func[, delay, param1, param2, ...]);
var timeoutId = window.setTimeout(code[, delay]);
  • timeoutId: 定时器ID
  • func: 延迟后执行的函数
  • code: 延迟后执行的代码字符串,不推荐使用原理类似eval()
  • delay: 延迟的时间(单位:毫秒),默认值为0
  • param1,param2: 向延迟函数传递而外的参数,IE9以上支持

setInterval: 以固定的时间间隔重复调用一个函数或者代码段·

var intervalId = window.setInterval(func, delay[, param1, param2, ...]);
var intervalId = window.setInterval(code, delay);
  • intervalId: 重复操作的ID
  • func: 延迟调用的函数
  • code: 代码段
  • delay: 延迟时间,没有默认值

setImmediate: 在浏览器完全结束当前运行的操作之后立即执行指定的函数(仅IE10和Node 0.10+中有实现),类似setTimeou(func, 0)

//code from http://caibaojian.com/javascript-timer.html
var immediateId = setImmediate(func[, param1, param2, ...]);
var immediateId = setImmediate(func);
  • immediateId: 定时器ID
  • func: 回调

requestAnimationFrame: 专门为实现高性能的帧动画而设计的API,但是不能指定延迟时间,而是根据浏览器的刷新频率而定。注意:不同屏幕的刷新频率不同,一般为60HZ,刷新频率越大速度越快。

var requestId = window.requestAnimationFrame(func);
  • func: 回调

上面简单的介绍了四种JS的定时器,而本文将会主要介绍比较常用的两种:setTimeout和setInterval。

二、举个栗子

1、setTimeout()函数 -- 普通定时器

//setTimeout()函数
window.onload = function(){
    num1 = document.getElementById("number1");	//获取容器对象
	selectTime1();    //执行定时器
}

//定时器函数
var timer;
function selectTime1(){
    clearTimeout(timer);    //清除上一个定时器
    timer = setTimeout(function(){
        num1.innerText = Math.round(Math.random()*100);
        selectTime1();    //执行完毕之后,再调用定时器
    },1000);
}

每隔一定的时间就会执行定时器timer,并最终再次调用selectTime1()函数,注意的是,在调用时必须要清楚上一个定时器,否则在一些事件中会同时存在多个计时器,这样的结果就是多个定时器时间一到就会同时执行,导致数据不准确等等。

2、setInterval()函数 -- 循环定时器

window.onload = function(){
    num2 = document.getElementById("number2");	
    btn = document.getElementById("btn");
    var state = false;    //定时器的初始状态
	btn.onclick = function(){
		if(state == false){
			selectTime2();        //执行循环定时器
    		state = true;
            btn.value = "暂停";
		}else{
			clearInterval(timer);    //关闭循环定时器
			state = false;
			btn.value = "开启";	
		}
	}
}

//重复定时函数
function selectTime2(){
    clearTimeout(timer);    //清除上一个定时器
    timer = setInterval(function(){
        num2.innerText = Math.round(Math.random()*100);    //循环执行的内容
    },1000);
}

需要注意的是,循环计时器顾名思义会每隔一定的时间内循环执行,不需要像setTimeout那样调用函数来达到循环定时的目的。如果是setTimeout和setInterval的话,它俩仅仅在执行次数上有区别,setTimeout执行一次、setInterval无限循环。·

注意:setTimeout只有在回调完成之后才会去调用下一次定时器,而setInterval则不管回调函数的执行情况,当到达规定时间就会在事件队列中插入一个执行回调的事件,所以在选择定时器的方式时需要考虑setInterval的这种特性是否会对你的业务代码有什么影响。还有一点需要注意的是,如果需要定时器的定时时间不断地发生变法,只有使用setTimeout()定时函数才是最简便的,相对于setInterval()循环定时函数,它的执行时间是固定,并不会因为内部执行内容的改变而发生改变,当然如果你清除掉当前循环定时器对象,然后改变循环的时间再执行循环定时器也是可以达到预期效果的,只是这样的话要比setTimeot()函数复杂的多。例如下面这样

window.onload = function() {
	num1 = document.getElementById("number1");
	num2 = document.getElementById("number2");

	selectTime1();

	var state = false;
	btn = document.getElementById("btn");
	btn.onclick = function() {
		if(state == false) {
			btn.value = "暂停";
			selectTime2();
			state = true;
		} else {
			btn.value = "开启";
			clearInterval(timer);
			state = false;

		}
	}
}

var timer, times = 1;
//自动定时器
function selectTime1() {
	clearTimeout(timer);
	timer = setTimeout(function() {
		if(times < 500) {
			num1.innerText = Math.round(Math.random() * 100);
			if(times < 100) {
				times += 1;
			} else if(times < 300) {
				times += 30;
			} else {
				times += 50;
			}
			selectTime1();
		}
	}, times);
}
//手动循环定时器
function selectTime2() {
    times = 100;
	clearTimeout(timer);
	timer = setInterval(function() {
		num2.innerText = Math.round(Math.random() * 100);
	}, times);
}

 

三、JS定时器的工作原理

了解一下定时器的工作原理,这里将用引用How JavaScript Timers Work中的例子来解释定时器的工作原理,该图为一个简单版的原理图。·

上图中,左侧数字代表时间,单位毫秒;左侧文字代表某一个操作完成后,浏览器去询问当前队列中存在哪些正在等待执行的操作;蓝色方块表示正在执行的代码块;右侧文字代表在代码运行过程中,出现哪些异步事件。该图大致流程如下:

  • 程序开始时,有一个JS代码块开始执行,执行时长约为18ms,在执行过程中有3个异步事件触发,其中包括一个setTimeout、鼠标点击事件、setInterval
  • 第一个setTimeout先运行,延迟时间为10ms,稍后鼠标事件出现,浏览器在事件队列中插入点击的回调函数,稍后setInterval运行,10ms到达之后,setTimeout向事件队列中插入setTimeout的回调
  • 当第一个代码块执行完成后,浏览器查看队列中有哪些事件在等待,他取出排在队列最前面的代码来执行
  • 在浏览器处理鼠标点击回调时,setInterval再次检查到到达延迟时间,他将再次向事件队列中插入一个interval的回调,以后每隔指定的延迟时间之后都会向队列中插入一个回调
  • 后面浏览器将在执行完当前队头的代码之后,将再次取出目前队头的事件来执行

这里只是对定时器的原理做一个简单版的描述,实际的处理过程比这个复杂。

 

猜你喜欢

转载自blog.csdn.net/Rao_Limon/article/details/88295768