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基础知识大集锦(一) 推荐收藏
Jan 13 Javascript
Jquery封装tab自动切换效果的具体实现
Jul 13 Javascript
Ajax局部更新导致JS事件重复触发问题的解决方法
Oct 14 Javascript
javascript高级选择器querySelector和querySelectorAll全面解析
Apr 07 Javascript
基于JavaScript实现前端文件的断点续传
Oct 17 Javascript
AngularJS过滤器filter用法分析
Dec 11 Javascript
前端把html表格生成为excel表格的实例
Sep 19 Javascript
node文件批量重命名的方法示例
Oct 23 Javascript
浅析vue中常见循环遍历指令的使用 v-for
Apr 18 Javascript
微信小程序onLaunch异步,首页onLoad先执行?
Sep 20 Javascript
深入理解Antd-Select组件的用法
Feb 25 Javascript
IDEA配置jQuery, $符号不再显示黄色波浪线的问题
Oct 09 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
php输出指定时间以前时间格式的方法
2015/03/21 PHP
PHP中的类型提示(type hinting)功能介绍
2015/07/01 PHP
PHP使用正则表达式获取微博中的话题和对象名
2015/07/18 PHP
php递归函数怎么用才有效
2018/02/24 PHP
Asp.net下利用Jquery Ajax实现用户注册检测(验证用户名是否存)
2010/09/12 Javascript
Javascript动态绑定事件的简单实现代码
2010/12/25 Javascript
给ListBox添加双击事件示例代码
2013/12/02 Javascript
IE浏览器中图片onload事件无效的解决方法
2014/04/29 Javascript
jQuery简易图片放大特效示例代码
2014/06/09 Javascript
jQuery.deferred对象使用详解
2016/03/18 Javascript
微信小程序 Storage API实例详解
2016/10/02 Javascript
Vue 固定头 固定列 点击表头可排序的表格组件
2016/11/25 Javascript
浅谈javascript中的事件冒泡和事件捕获
2016/12/28 Javascript
vue不通过路由直接获取url中参数的方法示例
2017/08/24 Javascript
详解http访问解析流程原理
2017/10/18 Javascript
element-ui table span-method(行合并)的实现代码
2018/12/20 Javascript
服务端预渲染之Nuxt(使用篇)
2019/04/08 Javascript
NodeJs操作MongoDB教程之分页功能以及常见问题
2019/04/09 NodeJs
js实现蒙版效果
2020/01/11 Javascript
Python映射拆分操作符用法实例
2015/05/19 Python
Python常用的文件及文件路径、目录操作方法汇总介绍
2015/05/21 Python
获取python的list中含有重复值的index方法
2018/06/27 Python
Python2比较当前图片跟图库哪个图片相似的方法示例
2019/09/28 Python
python 调用Google翻译接口的方法
2020/12/09 Python
廉价航班、机票和酒店:JustFly
2018/02/07 全球购物
大学旷课检讨书
2014/01/28 职场文书
生日宴会主持词
2014/03/20 职场文书
学生鉴定评语大全
2014/05/05 职场文书
关于读书的演讲稿600字
2014/08/27 职场文书
创先争优公开承诺书
2014/08/30 职场文书
群众路线教育查摆剖析材料
2014/10/10 职场文书
2014年消防工作总结
2014/11/21 职场文书
企业员工辞职信范文
2015/05/12 职场文书
2015年小学远程教育工作总结
2015/07/28 职场文书
小学音乐课教学反思
2016/02/18 职场文书
javascript代码简写的几种常用方式汇总
2021/08/23 Javascript