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 相关文章推荐
关于JavaScript中string 的replace
Apr 12 Javascript
解析Javascript中中括号“[]”的多义性
Dec 03 Javascript
js与jquery获取父元素,删除子元素的两种不同方法
Jan 09 Javascript
Bootstrap精简教程
Nov 27 Javascript
微信小程序-消息提示框实例
Nov 24 Javascript
概述一个页面从输入URL到页面加载完的过程
Dec 16 Javascript
基于JavaScript定位当前的地理位置
Apr 11 Javascript
微信小程序实现倒计时60s获取验证码
Apr 17 Javascript
解决vue页面DOM操作不生效的问题
Mar 17 Javascript
微信小程序实现默认第一个选中变色效果
Jul 17 Javascript
微信小程序中为什么使用var that=this
Aug 27 Javascript
vue使用video插件vue-video-player的示例
Oct 03 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
PHP4实际应用经验篇(4)
2006/10/09 PHP
PHP中func_get_args(),func_get_arg(),func_num_args()的区别
2013/09/30 PHP
Yii2 assets清除缓存的方法
2016/05/16 PHP
PHP-CGI远程代码执行漏洞分析与防范
2017/05/07 PHP
PHP通过GD库实现验证码功能示例
2019/02/23 PHP
windows系统php环境安装swoole具体步骤
2021/03/04 PHP
javascript之函数直接量(function(){})()
2007/06/29 Javascript
javascript常用方法、属性集合及NodeList 和 HTMLCollection 的浏览器差异
2010/12/25 Javascript
jQuery简单实现网页选项卡特效
2014/11/24 Javascript
jQuery事件绑定与解除绑定实现方法
2015/04/15 Javascript
js遍历json的key和value的实例
2017/01/22 Javascript
vue如何集成raphael.js中国地图的方法示例
2017/08/15 Javascript
cocos creator Touch事件应用(触控选择多个子节点的实例)
2017/09/10 Javascript
Node.js 使用递归实现遍历文件夹中所有文件
2017/09/18 Javascript
ionic2中使用自动生成器的方法
2018/03/04 Javascript
JQuery搜索框自动补全(模糊匹配)功能实现示例
2019/01/08 jQuery
js通过循环多张图片实现动画效果
2019/12/19 Javascript
vue2路由基本用法实例分析
2020/03/06 Javascript
基于javascript canvas实现五子棋游戏
2020/07/08 Javascript
python多线程编程方式分析示例详解
2013/12/06 Python
python实现定制交互式命令行的方法
2014/07/03 Python
python统计文本字符串里单词出现频率的方法
2015/05/26 Python
在PyCharm中实现关闭一个死循环程序的方法
2018/11/29 Python
Python实现去除列表中重复元素的方法总结【7种方法】
2019/02/16 Python
如何用border-image实现文字气泡边框的示例代码
2020/01/21 HTML / CSS
世界上最大的在线学习和教学市场:Udemy
2017/11/08 全球购物
欧洲品牌瓷器餐具网上商店:Porzellantreff.de
2018/04/04 全球购物
中国制造网:Made-in-China.com
2019/10/25 全球购物
英国著名的美容护肤和护发产品购物网站:Lookfantastic
2020/11/23 全球购物
Boolean b = new Boolean(“abcde”); 会编译错误码
2013/11/27 面试题
干部行政关系介绍信
2014/01/17 职场文书
餐厅销售主管职责范本
2014/02/19 职场文书
迎新晚会策划方案
2014/06/13 职场文书
网络研修心得体会
2016/01/08 职场文书
MySQL优化之如何写出高质量sql语句
2021/05/17 MySQL
Spring this调用当前类方法无法拦截的示例代码
2022/03/20 Java/Android