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 相关文章推荐
让textarea控件的滚动条怎是位与最下方
Apr 20 Javascript
JavaScript 对话框和状态栏使用说明
Oct 25 Javascript
JQuery index()方法使用代码
Jun 02 Javascript
xml转json的js代码
Aug 28 Javascript
CSS+jQuery实现的一个放大缩小动画效果
Sep 24 Javascript
javascript分页代码实例分享(js分页)
Dec 13 Javascript
JQuery打造省市下拉框联动效果
May 18 Javascript
JavaScript中数组的22种方法必学(推荐)
Jul 20 Javascript
JavaScript“尽快失败”的原则实例详解
Oct 08 Javascript
angular或者js怎么确定选中ul中的哪几个li
Aug 16 Javascript
Vue项目实现简单的权限控制管理功能
Jul 17 Javascript
解决ant design vue 表格a-table二次封装,slots渲染的问题
Oct 28 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
兼容PHP5的PHP目录管理函数库
2008/07/10 PHP
php 5.6版本中编写一个PHP扩展的简单示例
2015/01/20 PHP
PHP入门教程之操作符与控制结构流程详解
2016/09/09 PHP
详解PHP 7.4 中数组延展操作符语法知识点
2019/07/19 PHP
php操作redis常见方法示例【key与value操作】
2020/04/14 PHP
jquery实现盒子下拉效果示例代码
2013/09/12 Javascript
两种方法基于jQuery实现IE浏览器兼容placeholder效果
2014/10/14 Javascript
node.js中的socket.io的广播消息
2014/12/15 Javascript
JAVA四种基本排序方法实例总结
2015/07/24 Javascript
javascript实现简易计算器的代码
2016/05/31 Javascript
JS查找字符串中出现次数最多的字符
2016/09/05 Javascript
深入理解Node.js的HTTP模块
2016/10/12 Javascript
详解js的六大数据类型
2016/12/27 Javascript
给Easyui-Datebox设置隐藏或者不可用的解决方法
2017/05/26 Javascript
JS非空验证及邮箱验证的实例
2017/08/11 Javascript
详解vue渲染函数render的使用
2017/12/12 Javascript
layui实现table加载的示例代码
2018/08/14 Javascript
Vue 中使用富文本编译器wangEditor3的方法
2019/09/26 Javascript
vue data对象重新赋值无效(未更改)的解决方式
2020/07/24 Javascript
js实现鼠标切换图片(无定时器)
2021/01/27 Javascript
手动实现vue2.0的双向数据绑定原理详解
2021/02/06 Vue.js
[01:27]2014DOTA2展望TI 剑指西雅图IG战队专访
2014/06/30 DOTA
[59:53]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第二场 3月6日
2021/03/11 DOTA
遗传算法之Python实现代码
2017/10/10 Python
Python+OpenCV实现图像融合的原理及代码
2018/12/03 Python
Pandas数据离散化原理及实例解析
2019/11/16 Python
Python 写了个新型冠状病毒疫情传播模拟程序
2020/02/14 Python
比驿:全球酒店比价网
2018/06/20 全球购物
Linux内核产生并发的原因
2012/07/13 面试题
人力资源专业推荐信
2013/11/29 职场文书
初中地理教学反思
2014/01/11 职场文书
创业大赛策划书
2014/03/01 职场文书
电子商务求职信
2014/06/15 职场文书
监考失职检讨书
2015/01/26 职场文书
贷款担保书范本
2015/09/22 职场文书
基于Redis位图实现用户签到功能
2021/05/08 Redis