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 jqgrid 对含特殊字符json 数据的 Java 处理方法
Jan 01 Javascript
JavaScript高级程序设计(第3版)学习笔记4 js运算符和操作符
Oct 11 Javascript
常用的jQuery前端技巧收集
Dec 24 Javascript
JS中产生标识符方式的演变
Jun 12 Javascript
jquery实现用户信息修改验证输入方法汇总
Jul 18 Javascript
JavaScript数组对象赋值用法实例
Aug 04 Javascript
JS实现跟随鼠标的链接文字提示框效果
Aug 06 Javascript
js+CSS实现模拟华丽的select控件下拉菜单效果
Sep 01 Javascript
jQuery+PHP+MySQL实现无限级联下拉框效果
Feb 19 Javascript
jQuery实现简单滚动动画效果
Apr 07 Javascript
ionic环境配置及问题详解
Jun 27 Javascript
基于游标的分页接口实现代码示例
Nov 12 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
改德生G88 - 加装等响度低音提升电路
2021/03/02 无线电
php mssql 分页SQL语句优化 持续影响
2009/04/26 PHP
用 Composer构建自己的 PHP 框架之构建路由
2014/10/30 PHP
PHP的cookie与session原理及用法详解
2019/09/27 PHP
JavaScript arguments 多参传值函数
2010/10/24 Javascript
node.js中的querystring.escape方法使用说明
2014/12/10 Javascript
jquery.cookie.js使用指南
2015/01/05 Javascript
详解参数传递四种形式
2015/07/21 Javascript
js实现网页抽奖实例
2015/08/05 Javascript
如何防止JavaScript自动插入分号
2015/11/05 Javascript
利用JS提交表单的几种方法和验证(必看篇)
2016/09/17 Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
2017/03/30 Javascript
限时抢购-倒计时的完整实例(分享)
2017/09/17 Javascript
三种Webpack打包方式(小结)
2018/09/19 Javascript
JS双向链表实现与使用方法示例(增加一个previous属性实现)
2019/01/31 Javascript
微信打开网址添加在浏览器中打开提示的办法
2019/05/20 Javascript
在vue中封装方法以及多处引用该方法详解
2020/08/14 Javascript
vscode中的vue项目报错Property ‘xxx‘ does not exist on type ‘CombinedVueInstance<{ readyOnly...Vetur(2339)
2020/09/11 Javascript
解决VUE 在IE下出现ReferenceError: Promise未定义的问题
2020/11/07 Javascript
Python实现批量将word转html并将html内容发布至网站的方法
2015/07/14 Python
Python实现的rsa加密算法详解
2018/01/24 Python
Python实现socket非阻塞通讯功能示例
2019/11/06 Python
django连接mysql数据库及建表操作实例详解
2019/12/10 Python
基于Tensorflow:CPU性能分析
2020/02/10 Python
python小白切忌乱用表达式
2020/05/29 Python
Django ORM判断查询结果是否为空,判断django中的orm为空实例
2020/07/09 Python
html5指南-6.如何创建离线web应用程序实现离线访问
2013/01/07 HTML / CSS
澳大利亚时尚前卫设计师珠宝在线:Amber Sceats
2017/10/04 全球购物
在求职信中如何凸显个人优势
2013/10/30 职场文书
学生操行评语大全
2014/04/24 职场文书
爱祖国演讲稿
2014/05/04 职场文书
党委班子对照检查材料
2014/08/19 职场文书
银行求职信模板
2015/03/20 职场文书
2015年会计人员工作总结
2015/05/22 职场文书
如何设计高效合理的MySQL查询语句
2021/05/26 MySQL
排查并解决Oracle sysaux表空间异常增长
2022/04/20 Oracle