突然想起面试的时候一道面试题,当时答的不是很好,今天又重新研究了一下。
题目是这样的:
setTimeout(fuc,100);
这是一个简单的定时器,问题在于如果fuc函数的执行时间过于耗时,超过100毫秒,那会出现什么问题,怎么解决。
一、出现的问题就是fuc函数不会100ms之后执行,而是等到fuc函数执行完成之后执行setTimeout定时器,也意味着真实的延迟时间会比设定的时间长。
二、怎么解决,这就厉害了。
1、方法总体来说就是fuc的耗时减少
2、JS是单线程的执行,如果fuc函数为多线程也就是异步执行就ok了。
第一种方法不说了,就是方案设计上的废话。
第二种就厉害了。我们假设这个执行耗时的函数是一个循环。
function fuc(){
for(var i=0xA00000;i<0xFFFFFF;i++) { $("div").css("backgroundColor","#"+i.toString(16));}
}
这个代码片段不仅耗时,而且会把浏览器卡死。下面用settimeout一个伪多线程的方法setTimeout(fuc,0);
var timer;
var i=0x100000;
function func() {
timer = setTimeout(func, 0);
$("div").css("backgroundColor","#"+i.toString(16));}
if (i++ == 0xFFFFFF) clearInterval(timer);
}
timer = setTimeout(func, 0);
经过我的实测,不会卡死很流畅。
其中的缘由要讲一下setTimeout(fuc,0);的原理。
setTimeout的最小延迟时间为4ms也就意味这即使我们写0,在执行setTimeout(fuc,0);的时候也会自动编译成setTimeout(fuc,4);
所以相当于每隔4ms执行一次。效果就是setTimeout(f,0)必须要等到当前脚本的所有同步任务结束后才会执行。
热门评论
更正一点,setTimeout的最小延迟时间是与操作系统和浏览器内核有关的,时间都不一样(在Mac上的最小时间间隔是10毫秒,在Windows系统上的最小时间间隔大约是15毫秒)
楼主开始部分是要讲述setInterval()的问题把,后面部分是用setTimeout()来替代Interval()规避问题的