深入探究setTimeout 和setInterval
看了网上许多关于定时器的只是,有的说的比较乱,有的比较零碎,于是这里自己根据平时自己发现的问题总结一下。
setInterval(),setTimeout() 会返回一个值,一般认为是ID,将这个ID值传递给clearInterval(),clearTimeout() 可以取消执行。
clearInterval()和clearTimeout()其实是通用的,就是说你可以用 clearInterval() 取消 setTimeout() 执行,clearTimeout()同样可以取消 setInterval() 执行。
setTimeout和setInterval的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,定时器指定的代码,必须等到本次执行的所有代码都执行完,才会执行。
每一轮Event Loop时,都会将“任务队列”中需要执行的任务,一次执行完。setTimeout和setInterval都是把任务添加到“任务队列”的尾部。因此,它们实际上要等到当前脚本的所有同步任务执行完,然后再等到本次Event Loop的“任务队列”的所有任务执行完,才会开始执行。由于前面的任务到底需要多少时间执行完,是不确定的,所以没有办法保证,setTimeout和setInterval指定的任务,一定会按照预定时间执行。
setTimeout(“timeTask()”),100);
otherTask();
上面代码的setTimeout,指定100毫秒以后运行一个任务。但是,如果后面立即运行的任务(当前脚本的同步任务))非常耗时,过了100毫秒还无法结束,那么被推迟运行的timeTask就只有等着,等到前面的otherTask运行结束,才轮到它执行。
setInterval(function(){
console.log(2);
},1000);
(function (){
sleeping(3000);
})();
上面的第一行语句要求每隔1000毫秒,就输出一个2。但是,第二行语句需要3000毫秒才能完成,会发生什么结果呢?
结果就是等到第二行语句运行完成以后,立刻连续输出三个2,然后开始每隔1000毫秒,输出一个2。也就是说,setIntervel具有累积效应,如果某个操作特别耗时,超过了setInterval的时间间隔,排在后面的操作会被累积起来,然后在很短的时间内连续触发,这可能或造成性能问题(比如集中发出ajax请求)。
需要注意的是
根据HTML5标准,setTimeOut推迟执行的时间,最少是4毫秒。如果小于这个值,会被自动增加到4。这是为了防止多个setTimeout(f,0)语句连续执行,造成性能问题。
另一方面,浏览器内部使用32位带符号的整数,来储存推迟执行的时间。这意味着setTimeout最多只能推迟执行2147483647毫秒 (24.8天),超过这个时间会发生溢出,导致回调函数将在当前任务队列结束后立即执行,即等同于setTimeout(f,0)的效果。
调用定时任务,需要将被调用的方法以字符串的形式传入定时器,如
setTimeout(“timeTask()”),100);
http://www.jeffjade.com/2016/01/10/2016-01-10-javacript-setTimeout/
共同学习,写下你的评论
评论加载中...
作者其他优质文章