时间: 2015-11-17 00:00 栏目: JavaScript 浏览: 7530 赞: 20 踩: 25 字体: 大 中 小
以下为本篇文章全部内容:
大家好,我叶子,接下来继续讲一讲 Js的定时器。
JS 的定时器也是在学习JS中至关重要的一步,可能很多人用过这个定时器,但是对这个定时器的使用可能还会存在一些误区。这里 我准备花1篇来专门讲关于JS的定时器。
时间控制流程的函数如下
setInterval(); //定时执行 如每隔多少毫秒执行1次
setTimeout(); //延时执行 如过多少毫秒后执行
setImmediate(); //延时执行 ,当加载的代码执行完后 接着执行
nextTick(); //nodejs使用的 延时执行 在nodejs 中 和 setImmediate 功能类似
而 setImmediate 和 nextTick 在执行顺序上还是有一些不同的 nextTick 是并行异步执行的 而 setImmediate 是 串行 顺序执行的
还有需要注意的这些清理函数
clearInterval();
clearTimeout();
clearImmediate();
1 我们先做一个例子: 鼠标移到div上后 精度条 开始加载的效果。
<div id="loadlayout" style=" width: 400px; height: 50px; border: 1px solid #888"> <div id="load" style="width: 0px; height: 50px; background: #090; float: left;"></div> </div> <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js" type="text/javascript"></script> <script> (function ($) { $('#loadlayout').on('mouseover', function () { var pt = 0; var go = function () { console.log(pt); pt++; $('#load').css('width', pt + '%'); if (pt < 100) { setTimeout(go, 100); } }; setTimeout(go, 100); }); })(jQuery); </script>
在这个效果中 我们似乎觉得是没有问题的,但是细心的人就会发现,如果多次滑过 后 这个效果就会变得极其闪烁,那么这个问题是怎么形成的呢?
有些朋友说 我不用这个 setTimeout 换 clearInterval 到100后清理即可。于是建议我改代码成这样.
<div id="loadlayout" style=" width: 400px; height: 50px; border: 1px solid #888"> <div id="load" style="width: 0px; height: 50px; background: #090; float: left;"></div> </div> <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js" type="text/javascript"></script> <script> (function ($) { $('#loadlayout').on('mouseover', function () { var pt = 0; var timer= setInterval(function () { console.log(pt); pt++; $('#load').css('width', pt + '%'); if (pt >= 100) { window.clearInterval(timer); } }, 100); }); })(jQuery); </script>
视乎好像已经是到100 后清理了~~ 就没有问题了,可是还是出现闪烁的问题。然而照成这种闪烁 的原因 是因为 每移动一次鼠标经过 就会触发一个异步工作纤程去执行这个事件,而 同时有多个纤程在修改这这个 #load 的宽度。它被不同的纤程数据修改着!
这个问题 在很多初学者中都会经常碰到! 为了彻底解决这个问题~我们一旦要使用 这个定时器时 一定要注意 它可能会被多次触发!!
我们把上面代码改成这样:
<div id="loadlayout" style=" width: 400px; height: 50px; border: 1px solid #888"> <div id="load" style="width: 0px; height: 50px; background: #090; float: left;"></div> </div> <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js" type="text/javascript"></script> <script> (function ($) { var timer=null; $('#loadlayout').on('mouseover', function () { var pt = 0; if(timer) { window.clearInterval(timer); timer=null;} timer= setInterval(function () { console.log(pt); pt++; $('#load').css('width', pt + '%'); if (pt >= 100) { window.clearInterval(timer); timer=null; } }, 100); }); })(jQuery); </script>
2 接着我们讲讲计时器改什么时候使用
我在编程中是会尽量避免定时器的使用的 使用越少代码完整性越高,但是 我看多过很多人在书写JS代码是为了达到延时或者是等待某个啥的时候 做了一些定时器。
例如
某程序员 为一个 img 设置了 src 但是 想获取到这个 图片的高宽,这个时候他想到了使用定时器了!!
<img/> <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js" type="text/javascript"></script> <script> (function ($) { var img=$('img').attr('src','http://www.sunnyos.com/public/home/images/default.jpg'); console.log(img.width());//显然得不到结果 //某程序员这样做 setTimeout(function(){ console.log(img.width()); },500); })(jQuery); </script>
虽然这样也是可以得到高的,但是 谁都不敢保证500毫秒就能加载到图片,如果网速慢一点了呢? 如果网速快1点 也要等待500毫秒也不合适。
所以类似上面的代码 是不适合用 定时器去执行的 应避免滥用定时器,而多注重事件通知。
再有一种请求下 比如 你不需要 监听 body 的 load 事件 或者 body 已经 load 完成了!!
然而 你可能要加入一些代码 加入的代码不知道是多少个文件 那么这个时候 延迟执行就起到好处了!!
延迟执行 setImmediate 这个代码总在最后才执行
如
<script src="a.js" type="text/javascript"></script> <script src="b.js" type="text/javascript"></script> <script src="c.js" type="text/javascript"></script> .... .... <script src="n.js" type="text/javascript"></script>
我们等不到最后一个文件执行 或者说我们不知道最后一个文件是哪个。但是我们希望加载完成后 执行我们的一些操作 这个时候我们可以用延迟执行
setImmediate(function(){});
未完待续...
总赞数量:18274
总踩数量:128087
文章数量:29