1 重复定时器的使用
setInterval
是js中的间隔定时器,意味着每间隔多少时间就执行一次。
然而,在实际的运行当中可能并不是这样的。这就和js中的运行机制有关了。
这里的setInterval其实就是每间隔一定的时间,将程序添加到队列中,当然,这样有一个问题,如果我上一个定时器的程序还没有执行完,你就这样一直添加一直添加,这样只会导致程序连续运行好几次。
所以,js为了避免这种问题,实现的是,当队列中已经有一个定时器的副本的时候,再添加的定时器就会被跳过。
1.1 导致的问题: 1) 某些间隔会被跳过 2)多个定时器之间的代码执行间隔会比预期的小。
解决方案: 使用重复定时器。
setTimeout(function(){
程序处理代码
setTimeout(auguments.callee, interval)
}, interval)
// 这个思想就是,在定时器内部的程序代码处理后面再执行自身的代码,其实也就是回调。
// auguments.callee 表示的是当前运行该定时器的当前作用域的函数。
1.2 实际的应用 将一个div重复向右推动,直到到达200px处。
setTimeout(function(){
var Oid = document.getElementById('mydiv')
left = Oid.style.left + 5
Oid.style.left = left + 'px'
if (left < 200) {
setTimeout(arguments.callee, 500s)
}
}, 500s)
这种定时器的模式在js中的动画中非常常见。
2 yielding Processes
首先,js中的代码都是线性执行的,这意味着,如果你的执行代码中有一些大型的循环和数据处理程序在前面消耗过长的时间的话,就会导致js的程序阻塞。所以,如果这些类似for循环,不需要在短时间内执行完,而且不是顺序执行的,同时不需要同步完成的话,我们可以考虑以下的一种解决方案。
2.1 数组分块模式执行。
// data是每次循环要执行的数据
// context是process要执行的环境的上下文
// process 是要执行的函数
function yielding (data,process,context) {
setTimeout(function(data,context,process){
var mydata = data.shift()
process.call(context, mydata)
if (data.length > 0) {
setTimeout(arguments.callee,500ms)
}
},500ms)
}
2.2 实际的应用:依次向页面中添加li元素
var data = [12,13,14,22,56,66,444,333,12,56]
function process(data){
var oUL = document.getElementById('mydiv')
oUL.innerHtml+=''<li>' + data+'</li>''
}
yielding(data,process)
// 当然,如果你不想让数组的数据也发生改变的话,可以将数组的副本传递给它。
yielding(data.concat(), process)
// 其中。array.concat()意味着将数组的副本添加给了元素,不会改变原来的数组。
3 函数节流
像resize事件以及scroll事件。都会导致页面一直在监听执行函数,所以为了避免页面中一直不间断的执行函数,我们可以设置一个定时器,来间断执行函数。
什么意思呢?本来我们是一直每时每刻都在执行,因为这些事件是很多时间就会触发一次的。所以我们在监听的时候设置一个定时器,来间断执行函数。
function tottle(process,context){
clearTimeout(timeid)
var timeid = setTimeout(function(){
process.calll(context)
},500)
}
function resizeDiv () {
var div = document.getElementById('myDiv')
div.style.height = div.offsetWidth + 'px'
}
window.onresize = function(){
tottle(resizeDiv)
}
网友评论