setTimeout函数的神奇使用


Posted in Javascript onFebruary 26, 2017

【写在前面的胡言乱语】

自从大三开始实习之后,就没有写博客了,虽然学了很多东西,但是如果没有进行总结和分享,学的东西就很容易忘记,而且不进行分享,就不会手动去敲代码,这样对知识的理解就不够透彻。

现在毕业半年多了,最近学习了《JavaScript高级程序设计》这本书,受益匪浅,看了才知道虽然自己写了那么多JS,但是对JS的理解最多就只是中下水平。

现在看第二遍,边看边敲代码,边分享,希望看到这篇文章的你,能有所收获。

【这是正文】

《JavaScript高级程序设计》这本书里面,介绍了很多关于setTimeout函数的神奇使用,今天来介绍下第一个——使用setTimeout代替setInterval进行间歇调用。

书中是这么说的

“在开发环境下,很少使用间歇调用(setInterval),原因是后一个间歇调用很可能在前一个间歇调用结束前启动”。

这话怎么理解呢?

首先我们来看一下一般情况下的setInterval函数的使用,以及如何使用setTimeout代替setInterval

var executeTimes = 0;

var intervalTime = 500;

var intervalId = null;

 

// 放开下面的注释运行setInterval的Demo

intervalId = setInterval(intervalFun,intervalTime);

// 放开下面的注释运行setTimeout的Demo

// setTimeout(timeOutFun,intervalTime);

 

function intervalFun(){

executeTimes++;

console.log("doIntervalFun——"+executeTimes);

if(executeTimes==5){

clearInterval(intervalId);

}

}

 

function timeOutFun(){

executeTimes++;

console.log("doTimeOutFun——"+executeTimes);

if(executeTimes<5){

setTimeout(arguments.callee,intervalTime);

}

}

代码比较简单,我们只是在setTimeout的方法里面又调用了一次setTimeout,就可以达到间歇调用的目的。

重点来了,为什么作者建议我们使用setTimeout代替setInterval呢?setTimeout式的间歇调用和传统的setInterval间歇调用有什么区别呢?

区别在于,setInterval间歇调用,是在前一个方法执行前,就开始计时,比如间歇时间是500ms,那么不管那时候前一个方法是否已经执行完毕,都会把后一个方法放入执行的序列中。这时候就会发生一个问题,假如前一个方法的执行时间超过500ms,加入是1000ms,那么就意味着,前一个方法执行结束后,后一个方法马上就会执行,因为此时间歇时间已经超过500ms了。

书中没有给出代码证明这个结论,于是自己写了一段代码来验证。

var executeTimes = 0;

var intervalTime = 500;

var intervalId = null;

var oriTime = new Date().getTime();

 

// 放开下面的注释运行setInterval的Demo

intervalId = setInterval(intervalFun,intervalTime);

// 放开下面的注释运行setTimeout的Demo

// setTimeout(timeOutFun,intervalTime);

 

function intervalFun(){

executeTimes++;

var nowExecuteTimes = executeTimes;

var timeDiff = new Date().getTime() - oriTime;

console.log("doIntervalFun——"+nowExecuteTimes+", after " + timeDiff + "ms");

var delayParam = 0;

sleep(1000);

console.log("doIntervalFun——"+nowExecuteTimes+" finish !");

if(executeTimes==5){

clearInterval(intervalId);

}

}

 

function timeOutFun(){

executeTimes++;

var nowExecuteTimes = executeTimes;

var timeDiff = new Date().getTime() - oriTime;

console.log("doTimeOutFun——"+nowExecuteTimes+", after " + timeDiff + "ms");

var delayParam = 0;

sleep(1000);

console.log("doTimeOutFun——"+nowExecuteTimes+" finish !");

if(executeTimes<5){

setTimeout(arguments.callee,intervalTime);

}

}

 

function sleep(sleepTime){

var start=new Date().getTime();

while(true){

if(new Date().getTime()-start>sleepTime){


break;

}

}

}

(这里使用大牛提供的sleep函数来模拟函数运行的时间)

执行setInterval的Demo方法,看控制台

setTimeout函数的神奇使用

可以发现,fun2和fun1开始的间歇接近1000ms,刚好就是fun1的执行时间,也就意味着fun1执行完后fun2马上就执行了,和我们间歇调用的初衷背道而驰。

我们注释掉setInterval的Demo方法,放开setTimeout的Demo方法,运行,查看控制台

setTimeout函数的神奇使用

这下终于正常了,fun1和fun2相差了1500ms = 1000 + 500,fun2在fun1执行完的500ms后执行。

不知道你有没有和我一样脑洞大开,反正我是感觉视野又开阔了一点,setTimeout的妙用还有很多,下次接着聊!

Javascript 相关文章推荐
对textarea框的代码调试,而且功能上使用非常方便,酷
Jun 30 Javascript
javascript入门·对象属性方法大总结
Oct 01 Javascript
javascript multibox 全选
Mar 22 Javascript
JavaScript arguments 多参传值函数
Oct 24 Javascript
Jquery实现弹出层分享微博插件具备动画效果
Apr 03 Javascript
javascript读取xml实现javascript分页
Dec 13 Javascript
JavaScript返回0-1之间随机数的方法
Apr 06 Javascript
JavaScript验证Email(3种方法)
Sep 21 Javascript
深入探讨Vue.js组件和组件通信
Sep 12 Javascript
JavaScript实现的仿新浪微博原生态输入字数即时检查功能【兼容IE6】
Sep 26 Javascript
Element Notification通知的实现示例
Jul 27 Javascript
Javascript如何递归遍历本地文件夹
Aug 06 Javascript
node.js入门学习之url模块
Feb 25 #Javascript
从零学习node.js之利用express搭建简易论坛(七)
Feb 25 #Javascript
从零学习node.js之express入门(六)
Feb 25 #Javascript
Node.JS中事件轮询(Event Loop)的解析
Feb 25 #Javascript
走进javascript——不起眼的基础,值和分号
Feb 24 #Javascript
angular.js 路由及页面传参示例
Feb 24 #Javascript
实例解析js中try、catch、finally的执行规则
Feb 24 #Javascript
You might like
PHP常用正则表达式集锦
2014/08/17 PHP
跟我学Laravel之配置Laravel
2014/10/15 PHP
php数组键名技巧小结
2015/02/17 PHP
ThinkPHP安装和设置
2015/07/27 PHP
PHP执行linux命令常用函数汇总
2016/02/02 PHP
PHP Callable强制指定回调类型的方法
2016/08/30 PHP
PHP+jquery+CSS制作头像登录窗(仿QQ登陆)
2016/10/20 PHP
php实现购物车功能(以大苹果购物网为例)
2017/03/09 PHP
分享几种好用的PHP自定义加密函数(可逆/不可逆)
2020/09/15 PHP
封装了一个js图片轮换效果的函数
2011/09/28 Javascript
使用Math.floor与Math.random取随机整数的方法详解
2013/05/07 Javascript
web css实现整站样式互相切换
2013/10/29 Javascript
js用闭包遍历树状数组的方法
2014/03/19 Javascript
js Calender控件使用详解
2015/01/05 Javascript
Javascript验证Visa和MasterCard信用卡号的方法
2015/07/27 Javascript
jQuery实现批量判断表单中文本框非空的方法(2种方法)
2015/12/09 Javascript
AngularJS使用ngOption实现下拉列表的实例代码
2016/01/23 Javascript
页面间固定参数,通过cookie传值的实现方法
2017/05/31 Javascript
深入探究AngularJs之$scope对象(作用域)
2017/07/20 Javascript
postman+json+springmvc测试批量添加实例
2018/03/31 Javascript
如何使用less实现随机下雪动画详解
2019/01/02 Javascript
JavaScript如何借用构造函数继承
2019/11/06 Javascript
原生js实现贪食蛇小游戏的思路详解
2019/11/26 Javascript
解决Vue + Echarts 使用markLine标线(precision精度问题)
2020/07/20 Javascript
Python通过解析网页实现看报程序的方法
2014/08/04 Python
Python利用QQ邮箱发送邮件的实现方法(分享)
2017/06/09 Python
Python 实现字符串中指定位置插入一个字符
2018/05/02 Python
Python利用matplotlib做图中图及次坐标轴的实例
2019/07/08 Python
Html5页面二次分享的实现
2018/07/30 HTML / CSS
莫斯科珠宝厂官方网站:Miuz
2020/09/19 全球购物
捷科时代的软件测试笔试题
2015/11/09 面试题
介绍一下如何优化MySql
2016/12/20 面试题
机关出纳岗位职责
2014/04/03 职场文书
结对共建工作方案
2014/06/02 职场文书
返乡农民工证明
2015/06/24 职场文书
教你怎么用Python selenium操作浏览器对象的基础API
2021/06/23 Python