深入理解setTimeout和setinterval

  以前一直以为这两个函数就是简单了认为类似thread一样的东西, 认为会在一个时间片内, 并发的执行调用的函数, 似乎很好很强大, 但其实并不是如此, 实际的情况是javascript都是以单线程的方式运行于浏览器的javascript引擎中的, setTimeout和setInterval的作用只是把你要执行的代码在你设定的一个时间点插入js引擎维护的一个代码队列中, 插入代码队列并不意味着你的代码就会立马执行的,理解这一点很重要. 而且setTimeout和setInterval还有点不一样.

  先谈谈setTimeout  代码如下:

function click() {
// code block1...

setTimeout(function() {
// process ...
}, 200);
// code block2

}

假设我们给一个button的onclick事件绑定了此方法, 当我们按下按钮后, 肯定先执行block1的内容,
然后运行到setTimeout的地方, setTimeout会告诉浏览器说, "200ms后我会插一段要执行的代码给你的队列中",
浏览器当然答应了(注意插入代码并不意味着立马执行), setTimeout代码运行后, 紧跟其后的block2代码开始执行, 这里就开始说明问题了,
如果block2的代码执行时间超过200ms, 那结果会是如何? 或许按照你之前的理解, 会理所当然的认为200ms一到,
你的process代码会立马执行...事实是, 在block2执行过程中(执行了200ms后)process代码被插入代码队列,
但一直要等click方法执行结束, 才会执行process代码段, 从代码队列上看process代码是在click后面的, 再加上js以单线程方式执行,
所以应该不难理解. 如果是另一种情况, block2代码执行的时间<200ms, setTimeout在200ms后将process代码插入到代码队列,
而那时执行线程可能已经处于空闲状态了(idle), 那结果就是200ms后, process代码插入队列就立马执行了, 就让你感觉200ms后, 就执行了.

再看看setInterval
这里可能会存在两个问题:
1.时间间隔或许会跳过

2.时间间隔可能<定时调用的代码的执行时间

代码如下:

function click() {
// code block1...

setInterval(function() {
// process ...
}, 200);
// code block2

}

和上面一样我们假设通过一个click, 触发了setInterval以实现每隔一个时间段执行process代码

比如onclick要300ms执行完, block1代码执行完, 在5ms时执行setInterval, 以此为一个时间点,
在205ms时插入process代码, click代码顺利结束, process代码开始执行,
然而process代码也执行了一个比较长的时间, 超过了接下来一个插入时间点405ms, 这样代码队列后又插入了一份process代码,
process继续执行着, 而且超过了605ms这个插入时间点, 下面问题来,
可能你还会认为代码队列后面又会继续插入一份process代码...真实的情况是,由于代码队列中已经有了一份未执行的process代码,
所以605ms这个插入时间点将会被"无情"的跳过, 因为js引擎只允许有一份未执行的process代码, 说到这里不知道您是不是会豁然开朗呢...

为了这种情况你可以用一种更好的代码形式

代码如下:

setTimeout(function(){
//processing

setTimeout(arguments.callee, interval);
}, interval);

时间: 2024-08-10 19:18:28

深入理解setTimeout和setinterval的相关文章

深入理解定时器系列第一篇——理解setTimeout和setInterval

很长时间以来,定时器一直是javascript动画的核心技术.但是,关于定时器,人们通常只了解如何使用setTimeout()和setInterval(),对它们的内在运行机制并不理解,对于与预想不同的实际运行状况也无法解决.本文将详细介绍定时器的相关内容 setTimeout() setTimeout()方法用来指定某个函数或字符串在指定的毫秒数之后执行.它返回一个整数,表示定时器的编号,这个值可以传递给clearTimeout()用于取消这个函数的执行 以下代码中,控制台先输出0,大概过10

理解setTimeout和setInterval

setTimeout和setInterval,这两个js函数都是用来定时执行.setTimeout执行一次,setInterval执行多次. 问题出现在今天,使用setInterval是,设置执行速度为1ms.这时setInterval就出现了延迟.它并没有严格按照1ms的速度执行. var speed1=1; task1 = setInterval(function(){ var val1=parseInt(document.getElementById('font1').innerHTML)

Javascript异步编程之setTimeout与setInterval详解分析(一)

Javascript异步编程之setTimeout与setInterval 在谈到异步编程时,本人最主要会从以下三个方面来总结异步编程( 注意: 特别解释:是总结,本人也是菜鸟,所以总结不好的,请各位大牛多多原谅!) 1. setTimeout与setInterval详细分析基本原理. 接下来这篇博客会总结setTimeout和setInterval基本点,对于上面三点会分三篇博客分别来总结,对于知道上面三点的人,但是又不是非常了解全面知识点的码农来说,没有关系的,我们可以慢慢来学习,来理解,或

Javascript异步编程之setTimeout与setInterval详解

http://www.cnblogs.com/tugenhua0707/ 在谈到异步编程时,本人最主要会从以下三个方面来总结异步编程( 注意: 特别解释:是总结,本人也是菜鸟,所以总结不好的,请各位大牛多多原谅!) 1. setTimeout与setInterval详细分析基本原理. 接下来这篇博客会总结setTimeout和setInterval基本点,对于上面三点会分三篇博客分别来总结,对于知道上面三点的人,但是又不是非常了解全面知识点的码农来说,没有关系的,我们可以慢慢来学习,来理解,或者

setTimeout 与 setInterval

最新写代码中时,看到项目中有人用到了 setTimeout(fun,0),于是想总结一下.个人理解,如果有错误的地方还请指出.THX 要想理解JavaScript的定时器是如何工作的,先要明白 JavaScript 引擎是单线程的.这个可以理解为 javascript 引擎是一个服务员,它有一个服务的队列,所有的界面元素事件,定时触发器回调,异步请求回调都要在这个任务队列里排队,等待处理.所有任务都是一个最小单位,不会中断处理.这样就可以理解 setTimeout(fun,0) 了,它并不是代表

JS中的setTimeout和setInterval的区别

学了许久的javascript,发现其中非常常用的两个函数,就是setInterval和setTimeout函数,对这两个函数的理解,有时觉得很模糊,经过多次的试验,终于对它有了比较深入的了解.定义,setInterval()-- 间隔指定的毫秒数不停地执行指定的代码.setTimeout,延迟两秒调用函数,这个定义非常的简单,但是它并不像字面意思上那么的简 很多人都觉得这两个方法差不多,但是,实际上,他们差的很远呢     因为setTimeout(表达式,延时时间)在执行时,是在载入后延迟指

Javascript定时器(二)——setTimeout与setInterval

一.解释说明 1.概述 setTimeout:在指定的延迟时间之后调用一个函数或者执行一个代码片段 setInterval:周期性地调用一个函数(function)或者执行一段代码. 2.语法 setTimeout: var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]); var timeoutID = window.setTimeout(code, delay); timeoutID 是该延时操作的数字ID,

setTimeout,setInterval运行原理

function a() { setTimeout(function(){alert(1)},0); alert(2); } a(); 和其他的编程语言一样,Javascript中的函数调用也是通过堆栈实现的.在执行函数a的时候,a先入栈,如果不给alert(1)加setTimeout,那么alert(1)第2个入栈,最后是alert(2).但现在给alert(1)加上setTimeout后,alert(1)就被加入到了一个新的堆栈中等待,并"尽可能快"的执行.这个尽可能快就是指在a的

setTimeout OR setInterval?

setTimeout 和setInterval从字面上应该是可以知道其大意的.timeout:延时:interval:间隔: 两者的区别就像是它们自己的英文解释一样:setTimeout是延时执行,并且它只执行一次(ps:当然也有方法让它无限执行):setInterval是间隔式的执行,每隔多少时间就执行一次.它会不断地循环执行.举个小例子: 上面说到setTimeout可以实现循环执行,方法也很简单,就是用一个递归就可以了.(ps:递归可以理解为在一个函数里面再去调用它自己) 那么实现原理就是