zoukankan      html  css  js  c++  java
  • setTimeout setInterval 学习笔记

      两个都是定时函数,setTimeout()只执行一次,setInterval()按时间段循环执行。

      现在有这样一个问题,在函数中递归调用setTimeout()可以达到和setInterval()一样的效果,如下:

    1.
    function test() {
        setTimeout(test, 10);
        //do something
    }
    
    2.  
    function test(){...}
    setInterval(test, 10);

     

     看起来效果一样,但是John Resig告诉我们由于setInterval()的实现机制,导致上面两种方法大有区别:

    原文  http://ejohn.org/blog/how-javascript-timers-work/

    文章大意是,对函数func(),时间长度t::

    1.  javascript为单线程执行,因此同一时刻只能有一个函数执行。浏览器会从待执行队列q 中以一定优先级选择函数执行。
    2.  setTimeout: 从当前时刻开始计算,在t 时间后将func()加入待执行函数队列q。
    3.  setInterval: 从当前时刻开始计算,每隔t 时间会将func()加入q中一次。直到执行clearInterval()为止。

      setInterval()这样处理可能产生一个问题,当func()因为某些原因而延迟执行时,可能导致多个func()在短时间内执行多次。这可能由于func()自身执行时间过长,或者是q中其它函数竞争导致func()一直无法执行。这显然属于逻辑出了问题。

      实验:

     1 function test() {
     2     var t = new Date();
     3     console.log("start: "+ t.getSeconds() + "." + t.getMilliseconds());
     4 
     5     var times = 0;
     6     while((new Date() - t)<3000) {
     7         times++;
     8     }
     9 
    10     t = new Date();
    11     console.log("end: "+ t.getSeconds() + "." + t.getMilliseconds());
    12 }
    13 
    14 var id = setInterval(test,2000);

      每个test()执行时间为3s,每隔2s执行一次test()。那么1个test()还没有执行完第2个test()就已经加入到q中了。实验结果如下:

      可以看到test()函数连续执行,没有像预期一样每隔2s执行一次。

      而 setTimeout() 的处理方式就不会产生这种问题,由于setTimeout()每次都是基于当前时间,而且必须是在func()得到执行时才会产生下一次执行机会。则当CPU繁忙时其执行次数大大小于setInterval()方式。因此setTimeout()方式有在有助于缓解CPU与内存的压力,但是如果我们对func()的执行次数有要求还是需要使用setInterval(),因为该方法不会因为函数延迟执行导致执行次数减少。

     

    clearTimeout 与 clearInterval

      两者根据func()的注册id来取消尚未执行的函数,动作是将其从q中移除。但是两者都无法阻止正在执行的func(),此时func()会正常执行到结束。

      javascript单线程执行,javascript没有线程机制,猜测其不存在并发(javascript中没有sleep()方法)。所有程序一旦运行无法终止,因此不需要考虑setTimeout()产生id的并发问题。

      如果javascript存在并发,应将func()内部setTimeout()函数提至最前。对于其单线程是否存在并发,存疑。

  • 相关阅读:
    java执行cmd程序
    修改linux 默认ssh的22端口
    docker入门(一)
    关键字:心跳网络、oracle rac 网络异常宕机、packet reassembles failed 、UDP error 转载大佬的一篇文章
    记录数据库心跳网络异常,导致数据库宕机--推荐使用OSWBB监控主机
    python项目一键导入所有安装包
    weblogic 中间件利用bsu 漏洞补丁升级
    weblogic 控制台密码输入5次错误被锁 / 密码忘记 修改密码的方法
    oracle数据泵工作学习记录
    简单粗暴的给Linux系统配置本地yum 源
  • 原文地址:https://www.cnblogs.com/defghy/p/3560895.html
Copyright © 2011-2022 走看看