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 对话框和状态栏使用说明
Oct 25 Javascript
js正文内容高亮效果的实现方法
Jun 30 Javascript
将list转换为json失败的原因
Dec 17 Javascript
jquery实现的导航固定效果
Apr 28 Javascript
JavaScript中的pow()方法使用详解
Jun 15 Javascript
JavaScript动态设置div的样式的方法
Dec 26 Javascript
Node.js中Request模块处理HTTP协议请求的基本使用教程
Mar 31 Javascript
div实现自适应高度的textarea实现angular双向绑定
Jan 08 Javascript
利用HTML5+Socket.io实现摇一摇控制PC端歌曲切换
Jan 13 Javascript
浅谈js函数三种定义方式 &amp; 四种调用方式 &amp; 调用顺序
Feb 19 Javascript
Vue中通过属性绑定为元素绑定style行内样式的实例代码
Apr 30 Javascript
深入了解JS之作用域和闭包
Jun 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编程过程中需要了解的this,self,parent的区别
2009/12/30 PHP
在PHP中使用curl_init函数的说明
2010/11/02 PHP
php实现rc4加密算法代码
2012/04/25 PHP
更改localhost为其他名字的方法
2014/02/10 PHP
PHP和Shell实现检查SAMBA与NFS Server是否存在
2015/01/07 PHP
php 人员权限管理(RBAC)实例(推荐)
2017/05/24 PHP
js中几种去掉字串左右空格的方法
2006/12/25 Javascript
javascript下数值型比较难点说明
2010/06/07 Javascript
JS、CSS以及img对DOMContentLoaded事件的影响
2014/08/12 Javascript
js贪吃蛇网页版游戏特效代码分享(挑战十关)
2015/08/24 Javascript
js图片轮播效果实现代码
2020/04/18 Javascript
基于jQuery实现以手风琴方式展开和折叠导航菜单
2016/01/28 Javascript
js 获取当前web应用的上下文路径实现方法
2016/08/19 Javascript
jQuery简易时光轴实现方法示例
2017/03/13 Javascript
利用jQuery解析获取JSON数据
2017/04/08 jQuery
JS 实现banner图片轮播效果(鼠标事件)
2017/08/04 Javascript
React 组件渲染和更新的实现代码示例
2019/02/21 Javascript
vue组件数据传递、父子组件数据获取,slot,router路由功能示例
2019/03/19 Javascript
微信小程序如何访问公众号文章
2019/07/08 Javascript
vue 中 命名视图的用法实例详解
2019/08/14 Javascript
js面向对象之实现淘宝放大镜
2020/01/15 Javascript
Vue 解决通过this.$refs来获取DOM或者组件报错问题
2020/07/28 Javascript
Python3实现将文件归档到zip文件及从zip文件中读取数据的方法
2015/05/22 Python
Python新手们容易犯的几个错误总结
2017/04/01 Python
Python使用Phantomjs截屏网页的方法
2018/05/17 Python
python实现字符串加密成纯数字
2019/03/19 Python
python爬虫开发之PyQuery模块详细使用方法与实例全解
2020/03/09 Python
区分python中的进程与线程
2020/08/13 Python
python 输入字符串生成所有有效的IP地址(LeetCode 93号题)
2020/10/15 Python
关于多种方式完美解决Python pip命令下载第三方库的问题
2020/12/21 Python
Python创建简单的神经网络实例讲解
2021/01/04 Python
Parfumdreams英国:香水和化妆品
2019/05/10 全球购物
在C语言中"指针和数组等价"到底是什么意思?
2014/03/24 面试题
普通党员个人剖析材料
2014/10/08 职场文书
领导班子整改方案
2014/10/25 职场文书
2016五四青年节活动总结范文
2016/04/06 职场文书