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 表单验证扩展代码(一)
Oct 11 Javascript
jquery密码强度校验
Dec 02 Javascript
JavaScript+html5 canvas制作的圆中圆效果实例
Jan 27 Javascript
JS中创建函数的三种方式及区别
Mar 13 Javascript
基于MVC方式实现三级联动(JavaScript)
Jan 23 Javascript
jQuery DOM节点的遍历方法小结
Aug 15 jQuery
详解vue中axios的封装
Jul 18 Javascript
Vue自定义全局Toast和Loading的实例详解
Apr 18 Javascript
vue-router源码之history类的浅析
May 21 Javascript
深入理解javascript prototype的相关知识
Sep 19 Javascript
详细分析React 表单与事件
Jul 08 Javascript
jQuery实现移动端扭蛋机抽奖
Nov 08 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
人大复印资料处理程序_补充篇
2006/10/09 PHP
php数据结构与算法(PHP描述) 快速排序 quick sort
2012/06/21 PHP
PHPMailer发送HTML内容、带附件的邮件实例
2014/07/01 PHP
HR vs ForZe BO3 第二场 2.13
2021/03/10 DOTA
js 页面传参数时 参数值含特殊字符的问题
2009/12/13 Javascript
Javascript中的isNaN函数使用说明
2011/11/10 Javascript
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
2012/03/01 Javascript
向JavaScript的数组中添加元素的方法小结
2015/10/24 Javascript
理解JavaScript中Promise的使用
2016/01/18 Javascript
基于jQuery Ajax实现上传文件
2016/03/24 Javascript
js实现用户输入的小写字母自动转大写字母的方法
2017/01/21 Javascript
Android中Okhttp3实现上传多张图片同时传递参数
2017/02/18 Javascript
基于layer.js实现收货地址弹框选择然后返回相应的地址信息
2017/05/26 Javascript
使用Node.js实现RESTful API的示例
2017/08/01 Javascript
基于JavaScript实现五子棋游戏
2020/08/26 Javascript
uniapp电商小程序实现订单30分钟倒计时
2020/11/01 Javascript
[03:59]5分钟带你了解什么是DOTA2(第二期)
2017/02/07 DOTA
windows下wxPython开发环境安装与配置方法
2014/06/28 Python
在Python中使用next()方法操作文件的教程
2015/05/24 Python
python数据预处理之将类别数据转换为数值的方法
2017/07/05 Python
简单了解python模块概念
2018/01/11 Python
详解Django 中是否使用时区的区别
2018/06/14 Python
详解django中url路由配置及渲染方式
2019/02/25 Python
Python3显示当前时间、计算时间差及时间加减法示例代码
2019/09/07 Python
解决Python安装cryptography报错问题
2020/09/03 Python
button在IE6/7下的黑边去除方案
2012/12/24 HTML / CSS
CSS3 实现时间轴动画
2020/11/25 HTML / CSS
以色列的身体护理及家居香薰品牌:Sabon NYC
2018/02/23 全球购物
应届生人事助理求职信
2013/11/09 职场文书
2014年幼儿园植树节活动方案
2014/03/02 职场文书
公安机关查摆剖析材料
2014/10/10 职场文书
归元寺导游词
2015/02/06 职场文书
Django项目配置Memcached和Redis, 缓存选择哪个更有优势
2021/04/06 Python
MySQL系列之一 MariaDB-server安装
2021/07/02 MySQL
25张裸眼3D图片,带你重温童年的记忆,感受3D的魅力
2022/02/06 杂记
我家女友可不止可爱呢 公开OP主题曲无字幕动画MV
2022/04/11 日漫