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 相关文章推荐
js chrome浏览器判断代码
Mar 28 Javascript
JS 文件大小判断的实现代码
Apr 07 Javascript
cocos2dx骨骼动画Armature源码剖析(三)
Sep 08 Javascript
探究Javascript模板引擎mustache.js使用方法
Jan 26 Javascript
BootStrap Progressbar 实现大文件上传的进度条的实例代码
Jun 27 Javascript
基于d3.js实现实时刷新的折线图
Aug 03 Javascript
Vue.js常用指令汇总(v-if、v-for等)
Nov 03 Javascript
利用jQuery.Validate异步验证用户名是否存在(推荐)
Dec 09 Javascript
JS运动特效之同时运动实现方法分析
Jan 24 Javascript
Vue组件开发技巧总结
Mar 04 Javascript
浅谈layui数据表格判断问题(加入表单元素),设置单元格样式
Oct 26 Javascript
vue+elementUI(el-upload)图片压缩,默认同比例压缩操作
Aug 10 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 创建标签云函数代码
2010/05/26 PHP
解决Laravel无法使用COOKIE和SESSION的问题
2019/10/16 PHP
基于Laravel 多个中间件的执行顺序详解
2019/10/21 PHP
超清晰的document对象详解
2007/02/27 Javascript
jquery 表单取值常用代码
2009/12/22 Javascript
利用jQuery操作对象数组的实现代码
2011/04/27 Javascript
jQuery中serializeArray()与serialize()的区别实例分析
2015/12/09 Javascript
图解Sublime Text3使用技巧
2015/12/21 Javascript
JavaScript与jQuery实现的闪烁输入效果
2016/02/18 Javascript
js图片切换具体实现代码
2016/10/13 Javascript
浅谈jquery之on()绑定事件和off()解除绑定事件
2016/10/26 Javascript
基于Phantomjs生成PDF的实现方法
2016/11/07 Javascript
jQuery实现大图轮播
2017/02/13 Javascript
简单快速的实现js计算器功能
2017/08/17 Javascript
微信小程序中使用wxss加载图片并实现动画效果
2018/08/13 Javascript
Vue 打包体积优化方案小结
2020/05/20 Javascript
构建一个JavaScript插件系统
2020/10/20 Javascript
微信小程序实现点击导航标签滚动定位到对应位置
2020/11/19 Javascript
[00:12]DAC2018 no[o]ne亮相SOLO赛 他是否如他的id一样无人可挡?
2018/04/06 DOTA
[43:58]DOTA2-DPC中国联赛定级赛 LBZS vs SAG BO3第一场 1月8日
2021/03/11 DOTA
Pyspider中给爬虫伪造随机请求头的实例
2018/05/07 Python
linux安装python修改默认python版本方法
2019/03/31 Python
python实现人工智能Ai抠图功能
2019/09/05 Python
python时间与Unix时间戳相互转换方法详解
2020/02/13 Python
CSS3中的clip-path使用攻略
2015/08/03 HTML / CSS
HTML5 Web存储方式的localStorage和sessionStorage进行数据本地存储案例应用
2012/12/09 HTML / CSS
澳大利亚百货公司:David Jones
2018/02/08 全球购物
抽象方法、抽象类怎样声明
2014/10/25 面试题
一套带网友答案的.NET笔试题
2016/12/06 面试题
关于安全演讲稿
2014/05/09 职场文书
商务英语专业毕业生求职信
2014/07/06 职场文书
2014年人大工作总结
2014/12/10 职场文书
行政二审代理词
2015/05/25 职场文书
CentOS7安装GlusterFS集群以及相关配置
2022/04/12 Servers
Java 死锁解决方案
2022/05/11 Java/Android
Python可视化神器pyecharts绘制水球图
2022/07/07 Python