先思考:
3、定时器是如何实现的?
1、其实上面还可以在内部写个循环次数较大的循环,就不截图了,发现时间会延迟到580多秒甚至更多(根据循环而定)
2、无论是回调函数还是非回调函数都是在主线程执行的,可以把过程看成初始化代码+回调代码
3、要注意时间间隔并不是代表实际执行代码的时间,而是说何时将定时器的代码添加到事件队列当中
浏览器
是负责排序,指派某段代码在某个时间点的优先级
扩展:firefox定时器扩展功能:能确定定时器过多久才执行的
//仅 Firefox 中
setTimeout(function(diff){
if (diff > 0) {
//晚调用
} else if (diff < 0){
//早调用
} else {
//调用及时
}
}, 250);
在之前的博客中已经提到了时间处理函数,这里再复习一波
取消间歇调用的重要性要远远高于取消超时调用
,因为在不加干涉的情况下,间歇调用将会一直执行到页面卸载。任何其他代码实例时
,才将定时器代码添加到队列中,这确保了定时器代码加入到队列中的最小时间间隔为指定间隔
。用 setInterval()为onclick事件设置一个重复定时器,如果
定时器代码和事件处理程序花了差不多的时间,那么就会出现跳过间隔连续运行定时器代码的情况
setTimeout(function(){
//处理中
setTimeout(arguments.callee, interval);
}, interval);
复习:
arguments
的主要用途是保存函数参数, 但这个对象还有一个名叫callee
的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数
setTimeout(function(){
var div = document.getElementById("myDiv");
left = parseInt(div.style.left) + 5;
div.style.left = left + "px";
if (left < 200){
setTimeout(arguments.callee, 50);
}
}, 50);
代码解析:将div元素向右移动,左坐标在200像素的事后停止(很像之前canvas做的盒子来回移动小动画的简单实现,也是依靠坐标执行),在js动画中这样设置时间间隔就可以使用这个解决办法的模式
setTimeout(function(){
//取出下一个条目并处理
var item = array.shift();
process(item);
//若还有条目,再设置另一个定时器
if(array.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
解析:array 这个变量本质上就是一个“待办事宜”列表,它包含了要处理的项目
在上面例子里面shift可以用来获取队列中下一个要处理的项目,然后将其传递给某个函数
//三个参数:要处理的项目的数组,用于处理项目的函数,以及可选的运行该函数
的环境
function chunk(array, process, context){
setTimeout(function(){
var item = array.shift();
process.call(context, item);
if (array.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}
解析:
1、上面那个时间间隔100ms可以根据需要自己去更改,但是课本说这个时间是效果很好的
2、参数中那个环境参数当环境是全局环境的时候其实是不需要的
var data = [12,123,1234,453,436,23,23,5,4123,45,346,5634,2234,345,342];
function printValue(item){
var div = document.getElementById("myDiv");
div.innerHTML += item + "
";
}
chunk(data, printValue);
一旦某个函数需要花 50ms 以上的时间完成,那么最好看看能否将任务分割为一系列可以使用定时器的小任务——摘自《JavaScript高级程序