定时器的详解应用到背后的原理解析
前言
之前在研究css加载对DOM和js的影响时使用了下面的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
function h() {
console.log( 222 )
}
function k() {
console.log(1111)
}
setTimeout(function () {
h()
}, 0)
k()
</script>
</head>
<body>
</body>
</html>
上面的代码发生的结果如下:
明明是定时器先执行,延时0s,按照预期应该是立马执行;
为什么是k函数
先执行?这其中定时器的运作原理到底是什么?
定时器的执行时机
关于定时器最重要的是:设定的时间是指代码加入队列的时间,而不是何时执行代码。例如:
var btn = document.getElementById('my-btn');
btn.onclick = function () {
setTimeout(function () {
document.getElementById('message').style.visibility = 'visible'
}, 250)
}
onclick事件执行执行,会执行定时器。在onclick执行300ms时,会被添加到事件处理程序中,等待被执行,一旦时间线程空闲下来,便开始执行定时器中的内容,所以定时器中的代码执行一定是>=300ms的,用时间线图表示为:
setInterval重复定时器可能存在的问题
当使用setInterval时,仅当没有该定时器的任何其他代码实例时,才将定时器添加到队列中。这确保了定时器代码添加到队列中的最小时间间隔为指定时间间隔。
有时候会出现以下问题:
- 某些间隔会被跳过
- 多个定时的代码执行之间的间隔可能会比预期小
举例: 某个onclick事件使用serInterval设置了一个200ms间隔的重复定时器,如果时间处理程序花了300多ms时间完成,同时定时器也花了差不多的时间,就会同时出现跳过间隔且连续运行定时器代码的情况。如图:
解决方法: 可以尝试使用 链式setTimeout()
//链式使用
setTimeout(function () {
setTimeout(arguments.callee, interval)
}, interval)
setTimeout的应用:Yeilding Processes (进程暂停)
运行在浏览器中的JavaScript都被分配了一个确定数量的资源,不同于桌面应用往往能够随意控制他们要的内存大小和处理时间,Javascript被严格限制了,以防止恶意的Web程序员吧用的计算机搞挂了,其中一个限制是长时间运行脚本的制约,如果代码运行超过特定时长或者特定数量的语句就不让它继续执行,询问是允许其继续执行还是停止它。所有JavaScript开发人员的目标就是,确保用户永远不会再浏览器中看到这个令人费解的对话框。定时器是绕开此限制的方法之一
脚本运行时间长的2个原因:
- 过长的、过深嵌套的函数调用;
- 进行大量处理的循环;
这2种后者较为容易的被解决。
解决"进行大量处理的循环"的问题
可以使用数组分块
,这种方式必须满足的要求:
- 该处理不是必须同步完成
- 数据不是必须按顺序完成
实现代码:
function chunk(arr, process