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实现鼠标悬停显示提示信息窗口的方法
Apr 30 Javascript
jQuery简单实现input文本框内灰色提示文本效果的方法
Dec 02 Javascript
基于JavaScript如何实现ajax调用后台定义的方法
Dec 29 Javascript
JS实用技巧小结(屏蔽错误、div滚动条设置、背景图片位置等)
Jun 16 Javascript
Angular设置title信息解决SEO方面存在问题
Aug 19 Javascript
详解vue-router基本使用
Apr 18 Javascript
Angular.js指令学习中一些重要属性的用法教程
May 24 Javascript
Vuex实现计数器以及列表展示效果
Mar 10 Javascript
node基于puppeteer模拟登录抓取页面的实现
May 09 Javascript
vue axios数据请求get、post方法及实例详解
Sep 11 Javascript
vue2过滤器模糊查询方法
Sep 16 Javascript
JS拖动选择table里的单元格完整实例【基于jQuery】
May 28 jQuery
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』PHP截断函数mb_substr()使用介绍
2013/04/22 PHP
解析PHP实现多进程并行执行脚本
2013/06/18 PHP
php上传图片类及用法示例
2016/05/11 PHP
php lcg_value与mt_rand生成0~1随机小数的效果对比分析
2017/04/05 PHP
js自执行函数的几种不同写法的比较
2012/08/16 Javascript
javascript自启动函数的问题探讨
2013/10/05 Javascript
JavaScript动态创建div属性和样式示例代码
2013/10/09 Javascript
jquery实现手机发送验证码的倒计时代码
2014/02/12 Javascript
JavaScript中var关键字的使用详解
2015/08/14 Javascript
jQuery动画效果相关方法实例分析
2015/12/31 Javascript
基于jquery编写分页插件
2016/03/07 Javascript
使用JQuery 加载页面时调用JS的实现方法
2016/05/30 Javascript
阿里云ecs服务器中安装部署node.js的步骤
2016/10/08 Javascript
EasyUI Combobox设置默认值 获取text的方法
2016/11/28 Javascript
Node.js 使用递归实现遍历文件夹中所有文件
2017/09/18 Javascript
vue 项目常用加载器及配置详解
2018/01/22 Javascript
vue开发环境配置跨域的方法步骤
2019/01/16 Javascript
从理论角度讨论JavaScript闭包
2019/04/03 Javascript
产制造追溯系统之通过微信小程序实现移动端报表平台
2019/06/03 Javascript
vue+element实现图片上传及裁剪功能
2020/06/29 Javascript
python里将list中元素依次向前移动一位
2014/09/12 Python
举例详解Python中threading模块的几个常用方法
2015/06/18 Python
Python实现TCP/IP协议下的端口转发及重定向示例
2016/06/14 Python
python如何在终端里面显示一张图片
2016/08/17 Python
python操作列表的函数使用代码详解
2017/12/28 Python
python查看数据类型的方法
2019/10/12 Python
python opencv实现信用卡的数字识别
2020/01/12 Python
利用django model save方法对未更改的字段依然进行了保存
2020/03/28 Python
django自带的权限管理Permission用法说明
2020/05/13 Python
Python+OpenCV图像处理——实现直线检测
2020/10/23 Python
Mytheresa中国官网:德国时尚奢侈品商城
2017/08/04 全球购物
毕业生求职推荐信
2013/11/04 职场文书
学校节能宣传周活动总结
2014/07/09 职场文书
2014年乡镇卫生院工作总结
2014/11/24 职场文书
材料员岗位职责范本
2015/04/11 职场文书
李强优秀员工观后感
2015/06/16 职场文书