关于js定时器

Document

昨天找了一下午的bug,还是没有完全搞明白,今天才了解是加载时间问题,用js创建的元素加载比较慢,导致取不到js创建的元素的offsetHeight,然后发现了定时器setTimeout解决的问题,看到了下面这篇文章
看下面内容之前,看一小段代码,如果读者能说出代码的用意,那就没必要往下看了,因为你都懂。

	setTimeout(function(){

/* Some long block of code… */

setTimeout(arguments.callee, 10);

}, 10);

setInterval(function(){

/* Some long block of code… */

}, 10);

计时器是一个很牛X的东西,但是很多人其实只限于知道它的语法,缺乏对其原理的认识。计时器通过设定一定的时间段(毫秒)来异步的执行一段代码。因为 Javascript
是一个单线程语言,计时器提供了一种绕过这种语言限制来执行代码的能力。

今天就简单的来说下计时器的工作原理。

JavaScript 提供了三个函数来构建和操作计时器

1 var id = setTimeout(fn, delay);

2 var id = setInterval(fn, delay);

3 clearInterval(id); clearTimeout(id);

具体的语法我就不多说了,可以查手册。为了了解计时器的工作原理,有一个概念必须记在心里:时间延迟不能被保证。什么意思,就是说你这样写setTimeout(fn, 500)
并不代表fn肯定在500毫秒之后马上就执行,延迟很可能会更长。因为 JavaScript 是单线程语言,所有的异步事件(包括计时器、鼠标事件或者一个 XMLHttpRequest
完成)仅仅当程序执行期间有缺口的时候才会执行,不是你规定了什么时候就什么时候执行,要知道程序员不是万能的,你写的东西最终还是要看浏览器脸色的。

从上往下看,左面的数字代表时间(毫秒),右面的文字代表了一系列异步事件的设置和触发,中间则是代码块。最上面的 JavaScript
代码块可能是你在浏览器载入的时候执行的片段,大概耗时18毫秒,紧接着下面的 Mouse Click Callback 代码块可能是你一个鼠标事件触发时的回调函数,大概耗时11毫秒,依次类推。

JavaScript 的单线程特性决定了每次只能执行一块,所以当第一块代码执行的时候(它一共运行了18毫秒),本身构造了两个计时器,期间可能用户还点了一下鼠标(你有过在网页一打
开还没载完就在那乱点的情况吗)。按理说用户点完鼠标就应该马上执行那个回调函数,但是不行,JavaScript 执行只有一条道嘛,在那18毫秒没跑完之前,其他代码块想执行就只能
排队,没空间给你超车都。那两个计时器都是10毫秒的延迟,从图中可以看到,setTimeout也在那18毫秒执行结束之前触发了,没办法也排队吧。

终于,18毫秒后,天上一道神雷把前面的车直接劈成空气了,后面两个排队的可以过去了,但是还得一个一个,不能并列,那谁先过去呢?是不是两个人在那划拳?不是的,浏览器说的算
,浏览器说,鼠标单击事件先过去,setTimeout只能继续等11毫秒。注意看图,在鼠标事件回调函数执行的时候,又一个计时器事件触发了(setInterval),等着,而且必须排在set
Timeout的后面。

11毫秒过去了,setTimeout 终于可以过去了,注意看,setInterval 的第二次触发了,虽然它第一次都在排队呢,如果这个时候还向往常一样排队,最后是什么情况,setTimeout执行完
了,就会连续执行两个setInterval,你设置的延迟没用了都。所以浏览器还是比较智能的,它在处理setInterval的时候,如果发现已经有排队的,就直接把新来的 Kill 掉。

接着看,轮到排队的 setInterval 第一次触发开始执行了,它执行的时候,第三次触发又到了,这一次没有排队了,所以浏览器没把它 Kill
掉,给丫排队的机会,所以你会发现这两次的setInterval的执行没有间隔的,如果你做一个幻灯片,遇到这种情况就要好好想想自己的代码是不是有问题了。

最后,再也没有别的因素干扰了 setInterval 了(假如用户被 MM 叫走了),setInterval 就按照你想要的步骤执行了。

讲到这里,开头的代码可以理解了吧。

	setTimeout(function(){

/* Some long block of code… */

setTimeout(arguments.callee, 10);

}, 10);

setInterval(function(){

/* Some long block of code… */

}, 10);

这两个函数看起来效果一样,其实不然,第一个代码块总会延迟10毫秒执行,虽然大多时候是大于10毫秒的。而第二个每到10毫秒就尝试执行,不管之前的触发执行了没有。

总结起来四条

• JavaScript 引擎只有一个线程,它会迫使某些异步事件排队

• setTimeout 和 setInterval 在执行异步代码的时候有很大区别

• 假如一个计时器被阻止执行,它会等待知道遇到一个代码执行空隙,通常时间比预计的要长

• Intervals 可能会一个挨着一个执行,如果回调函数的执行时间大于间隔

时间: 2024-10-11 03:33:51

关于js定时器的相关文章

C#-WebForm JS定时器(转)

C#-WebForm JS定时器 JS定时器: 1.window.setTimeout(function(){},3000) 延迟3秒执行 2.window.setInterval(function(){},3000) 也叫重复器,每3秒重复相同的事件 关闭定时器: var timer = window.setTimeout(function(){ window.clearTimeout("timer"); },3000); var timer = window.setInterval

C#-WebForm JS定时器

JS定时器: 1.window.setTimeout(function(){},3000) 延迟3秒执行 2.window.setInterval(function(){},3000) 也叫重复器,每3秒重复相同的事件 关闭定时器: var timer = window.setTimeout(function(){ window.clearTimeout("timer"); },3000); var timer = window.setInterval(function(){ wind

移动Web与js定时器暂停或不准确计时的问题解决

PC 上的 Firefox.Chrome 和 Safari 等浏览器,都会自动把未激活页面中的 JavaScript 定时器(setTimeout.setInterval)间隔最小值改为 1 秒以上:而移动设备上的浏览器往往会直接冻结未激活页面上的所有定时器」.今天继续聊一聊 JavaScript 定时器与移动 Web 这个话题. 计时器 最简单的计时器只需要一个时间变量和固定间隔运行的函数就可以了,定期把上一次时间(默认为系统初始时间)加上运行间隔就是当前时间了.在 PC 上,这样实现的计时器

js定时器的使用(实例讲解)

js定时器的使用(实例讲解) 作者: 字体:[增加 减小] 类型:转载 时间:2014-01-06我要评论 本篇文章主要介绍了js中定时器的使用方法.需要的朋友可以过来参考下,希望对大家有所帮助 在javascritp中,有两个关于定时器的专用函数,分别为: 1.倒计定时器:timename=setTimeout("function();",delaytime);2.循环定时器:timename=setInterval("function();",delaytime

js 定时器用法详解——setTimeout()、setInterval()、clearTimeout()、clearInterval()

  在js应用中,定时器的作用就是可以设定当到达一个时间来执行一个函数,或者每隔几秒重复执行某段函数.这里面涉及到了三个函数方法:setInterval().setTimeout().clearInterval(),本文将围绕这三种函数的用法,来实现定时器的功能,需要的朋友可以过来参考下,喜欢的可以点波赞,或者关注一下本人,希望对大家有所帮助. 定时器的应用需求: 1.设定一个时间,当时间到达的时候执行函数----比如:倒计时跳转页面等等. 2.每隔一段时间重复执行某段函数----比如抢票软件,

JS 定时器的4种写法及介绍

JS提供了一些原生方法来实现延时去执行某一段代码,下面来简单介绍一下setTiemout.setInterval.setImmediate.requestAnimationFrame. 一.什么是定时器 JS提供了一些原生方法来实现延时去执行某一段代码,下面来简单介绍一下 setTimeout: 设置一个定时器,在定时器到期后执行一次函数或代码段 var timeoutId = window.setTimeout(func[, delay, param1, param2, ...]); var

js定时器和this常见误区

定时器: js定时器有两种方法:setInterval(func,毫秒)和setTimeout(func,毫秒) 区别:setInterval()是间隔周期无限循环直到清除,而setTimeout()只执行一次,所以使用定时器是否循环就可以甄别选择 相同:都是先间隔指定的毫秒后执行函数 this: js中this和jquery中this 相同点:都是按照谁调用的就指向谁. 案例1: var name = "jack"; var getName=function() { return t

JS定时器做物体运动

JS定时器是函数 setInterval(函数体/函数名  , 时间) 清楚定时器 clearInterval(函数) 时间单位(毫秒) 1000毫秒  = 1秒 首先我们要知道用JS定时器能干什么?定时器的原理是什么? 我的理解为,定时器是能让一个物体根据规定的时间做规定的移动,而物体运动是怎样的效果呢?你可以理解为一个人走路,要走到某个位置,要走到这个位置肯定是一步步移动才能达到,而不是瞬间就到达的,所以定时器的作用更像是让物体像人一样走到相应的位置 比如: 规定一个横形状方块,其中包裹一个

js定时器的一些小问题

1 js中定时器分为两种:setInterval和setTimeout, 但是在代码的执行中,定时器的优先级最低,系统里其他不在执行的时候,它才开始.例子如下: 2 3 <script> 4 window.onload=function(){ 5 setInterval(function(){ 6 alert(1); 7 },10); 8 for(var i=0;i<1000000;i++){ 9 for(var j=0;j<1000000;j++){ 10 var a=10; 1

js 定时器

1. 设置定时器 语法:setInterval(函数,时间) 注意: 函数书写时不能带括号 setInterval(fn,1000)//正确 setInterval(fn(),1000)//错误 时间的最小设置不小于14ms 2. 清除定时器 语法:clearInterval(所清除的定时器名称) 3. 实例探究 js部分 window.onload = function() { var timer = null; var num = 0; var i = 0; var arr=['red','