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中json对象的复制方式介绍(数组及对象)
Jun 08 Javascript
js实现的类似于asp数据字典的数据类型代码实例
Sep 03 Javascript
jQuery焦点控制图层展示延迟隐藏的方法
Mar 09 Javascript
JavaScript是如何实现继承的(六种方式)
Mar 31 Javascript
JS编写函数实现对身份证号码最后一位的验证功能
Dec 29 Javascript
谈谈JavaScript数组常用方法总结
Jan 24 Javascript
Node.js 使用命令行工具检查更新
Jun 08 Javascript
Vuex入门到上手教程
Jun 20 Javascript
vue-cli 脚手架基于Nightwatch的端到端测试环境的过程
Sep 30 Javascript
JS获取当前时间的实例代码(昨天、今天、明天)
Nov 13 Javascript
vue elementui el-form rules动态验证的实例代码详解
May 23 Javascript
vue-cli3 取消eslint校验代码的解决办法
Jan 16 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 数组的一个悲剧?
2011/05/11 PHP
php中利用str_pad函数生成数字递增形式的产品编号
2013/09/30 PHP
PHP实现生成唯一编号(36进制的不重复编号)
2014/07/01 PHP
php时间戳转换代码详解
2019/08/04 PHP
ThinkPHP 5.1 跨域配置方法
2019/10/11 PHP
父窗口获取弹出子窗口文本框的值
2006/06/27 Javascript
javascript解析json数据的3种方式
2014/05/08 Javascript
js事件监听机制(事件捕获)总结
2014/08/08 Javascript
JavaScript创建闭包的两种方式的优劣与区别分析
2015/06/22 Javascript
详解Webwork中Action 调用的方法
2016/02/02 Javascript
Three.js学习之几何形状
2016/08/01 Javascript
D3.js进阶系列之CSV表格文件的读取详解
2017/06/06 Javascript
提高Node.js性能的应用技巧分享
2017/08/10 Javascript
jquery select插件异步实时搜索实例代码
2017/10/20 jQuery
ES6下子组件调用父组件的方法(推荐)
2018/02/23 Javascript
JS常用的几种数组遍历方式以及性能分析对比实例详解
2018/04/11 Javascript
基于vue-cli 路由 实现类似tab切换效果(vue 2.0)
2019/05/08 Javascript
浅谈JavaScript中等号、双等号、 三等号的区别
2020/08/06 Javascript
[58:42]DOTA2上海特级锦标赛C组败者赛 Newbee VS Archon第一局
2016/02/27 DOTA
Python使用multiprocessing创建进程的方法
2015/06/04 Python
用Python将一个列表分割成小列表的实例讲解
2018/07/02 Python
python将一组数分成每3个一组的实例
2018/11/14 Python
python获取时间及时间格式转换问题实例代码详解
2018/12/06 Python
Python使用Shelve保存对象方法总结
2019/01/28 Python
python多线程并发及测试框架案例
2019/10/15 Python
浅析python内置模块collections
2019/11/15 Python
使用OpenCV-python3实现滑动条更新图像的Canny边缘检测功能
2019/12/12 Python
Python Django form 组件动态从数据库取choices数据实例
2020/05/19 Python
Pandas把dataframe或series转换成list的方法
2020/06/14 Python
英国网上购买肉类网站:Great British Meat
2018/10/17 全球购物
美国最大婚纱连锁店运营商:David’s Bridal
2019/03/12 全球购物
罗马尼亚在线杂货店:Pilulka.ro
2019/09/28 全球购物
财会自我鉴定范文
2013/12/27 职场文书
党政领导班子民主生活会整改措施
2014/09/18 职场文书
教师廉政准则心得体会
2016/01/20 职场文书
javascript条件式访问属性和箭头函数介绍
2021/11/17 Javascript