setTimeout函数的神奇使用

【写在前面的胡言乱语】

  自从大三开始实习之后,就没有写博客了,虽然学了很多东西,但是如果没有进行总结和分享,学的东西就很容易忘记,而且不进行分享,就不会手动去敲代码,这样对知识的理解就不够透彻。

现在毕业半年多了,最近学习了《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方法,看控制台

  可以发现,fun2和fun1开始的间歇接近1000ms,刚好就是fun1的执行时间,也就意味着fun1执行完后fun2马上就执行了,和我们间歇调用的初衷背道而驰。

  我们注释掉setInterval的Demo方法,放开setTimeout的Demo方法,运行,查看控制台

  这下终于正常了,fun1和fun2相差了1500ms = 1000 + 500,fun2在fun1执行完的500ms后执行。

  不知道你有没有和我一样脑洞大开,反正我是感觉视野又开阔了一点,setTimeout的妙用还有很多,下次接着聊!

(0)

相关推荐

  • jQuery setTimeout()函数使用方法

    setTimeout()从载入后延迟指定的时间去执行一个表达式或者是函数;仅执行一次 ;和window.clearTimeout一起使用. 我在 复制代码 代码如下: $(document).ready(function(){setTimout(test(),200); function test() { alert(1); } }); 只会执行一次,有朋友说可以使用 复制代码 代码如下: setInterval ("showTime()", 5000);function showTi

  • JS中setInterval、setTimeout不能传递带参数的函数的解决方案

    在JS中无论是setTimeout还是setInterval,在使用函数名作为调用句柄时都不能带参数,而在许多场合必须要带参数, 这就需要想方法解决. 一.采用字符串形式:--(缺陷)参数不能被周期性改变 setInterval("foo(id)",1000); 二.匿名函数包装 (推荐) 复制代码 代码如下: window.setInterval(function() { foo (id); }, 1000); 这样就可以周期性执行foo(id)这个函数,而且把变量id传递进去: 三

  • setTimeout函数兼容各主流浏览器运行执行效果实例

    目前这个setTimeout可以很好地兼容IE6,7,8,9以及谷歌浏览器Chrome,火狐浏览器FireFox,苹果浏览器Safari,Opera. setTimeout是一个很不错的函数,网站页面前端工程师经常将其用于几秒后执行的动作.setTimeout这个JS内置函数其用法也很简单,下面是setTimeout()的函数说明以及用法详解和实例.示例代码: setTimeout()的作用是指定在多少毫秒后执行一个JS函数或者表达式代码 setTimeout的用法.语法.参数:setTimeo

  • js函数使用技巧之 setTimeout(function(){},0)

    这个立刻的结果是: 浏览器会在文档内容处于稳定状态后立刻执行,这样就达到了和<script defer='defer'>或者<body onload="fun()">一样的效果. 更应该看到的是,此函数更优于上述方法,前面两个函数只能静态时刻处理(文档第一次载入的时候),而在系统开发中,常常由于查询.更新等操作后,文档的内容会刷新,这样就可以利用setTimeout的特点,使代码能在页面内容稳定后再执行!

  • javascript setTimeout()传递函数参数(包括传递对象参数)

    于是,上网查找了一下,用了另一种写法setTimeout("fun("+参数+")", 1000),还是不行,但是以上写法在传递form表单的textarea是可以的,比如hml是这样: 复制代码 代码如下: <body> <div class="main"> <div id="showpane" class="showpane"> </div> <di

  • 给c#添加SetTimeout和SetInterval函数

    调用示例: 执行效果: 2. 实现代码: 复制代码 代码如下: /// <summary>  2         /// 在指定时间过后执行指定的表达式  3         /// </summary>  4         /// <param name="interval">事件之间经过的时间(以毫秒为单位)</param>  5         /// <param name="action">要执

  • js函数setTimeout延迟执行的简单介绍

    setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. 语法: setTimeout(code,millisec) 参数: code (必需):要调用的函数后要执行的 JavaScript 代码串. millisec(必需):在执行代码前需等待的毫秒数. 提示: setTimeout() 只执行 code 一次.如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout().实例: 复制代码 代码如下: function timed

  • 解决火狐浏览器下JS setTimeout函数不兼容失效不执行的方法

    今天检查自己用JQuery+AJAX+PHP做的网站后台登录检测,发现登陆成功后执行页面跳转函数这段JavaScript(JS)代码特效在IE和谷歌浏览器Chrome下都可以很好地执行,兼容性还不错.结果到了火狐(FireFox)浏览器下setTimeout这个JS内置函数不执行了,无效了,也没报错!打开FireBUG指望它能检测出JS的错误,结果没用...Javascript(JS)脚本代码在各浏览器下的兼容是一个很头疼的问题,经过一番调试和搜索,终于解决了setTimeout这个JS代码在火

  • 深入理解setTimeout函数和setInterval函数

    前几天学了js,看到了两个非常有趣的函数,他们分别是setTimeout函数和setInterval函数,这两个函数能使网页呈现非常一些网页中比较常见的效果,比如说图片轮播,等一些非常好玩的效果.下面就来一起来了解这两个函数吧! 一setTimeout函数和setInterval函数的语法以及应用 1.setTimeout函数 定义和用法:setTimeout()方法用于在指定的毫秒数后调用函数或计算表达式. 语法:setTimeout(code,millisec); 参数: code (必需)

  • 定时器(setTimeout/setInterval)调用带参函数失效解决方法

    首先来看下定时器的用法 1. setInterval(code,millisec[,"lang"]) setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式. 参数 描述 code 必需,要调用的函数或要执行的代码串. millisec 必需,周期性执行或调用 code 之间的时间间隔,以毫秒计.2.setTimeout(code,millisec) setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. 参数 描述 code 必需,要调用

随机推荐