定时器的高级运用 优化

时间:2021-05-17 00:18:46
JavaScript是单线程的,因此在JavaScript的主执行线程上,有一个需要执行的代码队列,例如当一个按钮被点击,那么他的event handle就被添加到队列并在线程让出来的时候执行。所以说并没有真正意义上的马上执行,需要等到线程空闲才可以。
 
定时1秒后执行某些代码,只是说把这些代码添加到一秒后的执行队列里,如果到时有程序占用着线程,就得延迟。
 
只有火狐有一个对象来判断是否延迟了:
setTimeout(function(diff){
if (diff > 0) {
//call is late
} else if (diff < 0){
//call is early
} else {
//call is on time
}
}, 250);
 
当执行完一段代码,JavaScript执行线程会产出一个空闲时间,所以页面上的其他操作才能进行。
 
repeating timers
setInterval的问题在于可能间隔太小,而运行时间太长,有个别可能就执行不了了。为了避免这个问题可以使用setTimeout回调函数来嵌套。
 
setTimeout(function(){
//processing
setTimeout(arguments.callee, interval);
}, interval);
 
每一个浏览器窗口都有自己的执行队列,这意味着定时器在cross-frame或者cross-window时会出现争抢局面当同步运行代码。因此最好在接收方弄一个定时器来执行接收到的代码。
 
yielding processes
JavaScript在浏览器运行时所获得资源是有效的,防止恶意Web程序不会让用户电脑宕机。其中一个限制就是long-running 脚本限制,超过最大时间或者一定状态数量,浏览器就会弹出警告,问用户是继续让它执行还是结束。。。。
 
如果处理结果不会阻碍其他代码,用异步处理取代同步处理。如果数据没有依赖关系,可以推迟部分数据处理
 
array chunking 创建一个需要处理数据的队列,用定时器来控制
function chunk(array, process, context){
setTimeout(function(){
var item = array.shift();
process.call(context, item);
if (array.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}
 
使用这个函数的时候传进入的数组是会改变的,如果想保留原来的就传一个复制的
chunk(data.concat(), process);
 
当有一个函数执行超过50毫秒,最好就分成小部分来执行。
 
function throttling
Dom操作需要更多的CPU和内存,例如在ie使用onresize就容易奔溃,因为高频的改变导致很多计算。
 
throttling的原理是一些代码不应该反复执行没有中断,通过定时和取消定时来避免多余运算。
function throttle(method, context) {
clearTimeout(method.tId);
method.tId= setTimeout(function(){
method.call(context);
}, 100);
}
这样当你进行类似改变窗口大小事件时,就可以节省大量无谓运算了。