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 相关文章推荐
jQuery autocomplete插件修改
Apr 17 Javascript
15款优秀的jQuery导航菜单插件分享
Jul 19 Javascript
ASP.NET jQuery 实例4(复制TextBox的文本到本地剪贴板上)
Jan 13 Javascript
jQuery实现的Tab滑动选项卡及图片切换(多种效果)小结
Sep 14 Javascript
谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
Feb 15 Javascript
jQuery+Ajax实现限制查询间隔的方法
Jun 07 Javascript
jQuery 实现ajax传入参数含有特殊字符的方法总结
Oct 17 Javascript
jQuery用noConflict代替$的实现方法
Apr 12 jQuery
vue.js中mint-ui框架的使用方法
May 12 Javascript
解决vue props 拿不到值的问题
Sep 11 Javascript
详解可以用在VS Code中的正则表达式小技巧
May 14 Javascript
JS中的算法与数据结构之链表(Linked-list)实例详解
Aug 20 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
在PWS上安装PHP4.0正式版
2006/10/09 PHP
Symfony2在Nginx下的配置方法图文教程
2016/02/04 PHP
判断目标是否是window,document,和拥有tagName的Element的代码
2010/05/31 Javascript
IE下通过a实现location.href 获取referer的值
2014/09/04 Javascript
jQuery Mobile页面返回不需要重新get
2016/04/26 Javascript
基于BootStrap Metronic开发框架经验小结【四】Bootstrap图标的提取和利用
2016/05/12 Javascript
通过JS获取Request.QueryString()参数的值实现方法
2016/09/27 Javascript
jQuery焦点图左右转换效果
2016/12/12 Javascript
zTree节点文字过多的处理方法
2017/11/24 Javascript
浅析JavaScript中的特殊数据类型
2017/12/15 Javascript
JS实现图片转换成base64的各种应用场景实例分析
2018/06/22 Javascript
微信小程序开发之map地图组件定位并手动修改位置偏差
2019/08/17 Javascript
jquery 回调操作实例分析【回调成功与回调失败的情况】
2019/09/27 jQuery
vue+elementui 对话框取消 表单验证重置示例
2019/10/29 Javascript
package.json中homepage属性的作用详解
2020/03/11 Javascript
vue 子组件和父组件传值的示例
2020/09/11 Javascript
[02:01]大师之路——DOTA2完美大师赛11月论剑上海
2017/11/06 DOTA
如何解决django配置settings时遇到Could not import settings 'conf.local'
2014/11/18 Python
Django的数据模型访问多对多键值的方法
2015/07/21 Python
python中的decorator的作用详解
2018/07/26 Python
使用python的pexpect模块,实现远程免密登录的示例
2019/02/14 Python
Python常用爬虫代码总结方便查询
2019/02/25 Python
python matplotlib画图库学习绘制常用的图
2019/03/19 Python
详解【python】str与json类型转换
2019/04/29 Python
python hough变换检测直线的实现方法
2019/07/12 Python
Python3 JSON编码解码方法详解
2019/09/06 Python
快速了解Python开发环境Spyder
2020/06/29 Python
StubHub美国:购买或出售您的门票
2019/07/09 全球购物
上海中网科技笔试题
2012/02/19 面试题
应届护士求职信范文
2014/01/26 职场文书
银行优秀员工事迹
2014/02/06 职场文书
机关干部作风建设剖析材料
2014/10/23 职场文书
2015年部门工作总结范文
2015/03/31 职场文书
教师节老师寄语
2015/05/28 职场文书
2016年党员创先争优公开承诺书
2016/03/25 职场文书
浅谈如何写好演讲稿?
2019/06/12 职场文书