• 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()函数提至最前。对于其单线程是否存在并发,存疑。

  • 相关阅读:
    负载均衡,分布式,集群的理解,多台服务器代码如何同步
    浅谈控制反转与依赖注入
    Jetbrains系列产品重置试用方法
    讲述一下一个还没毕业的科班程序猿的求职历程
    一个在求职路上挣扎的萌新
    用C#操作文件/文件夹(删除,复制,移动)
    随笔-关于公网IP无法访问服务器的解决办法
    C/s从文件(TXT)中读取数据插入数据库
    Sql Server + ADO.NET
    进程。线程与线程池
  • 原文地址:https://www.cnblogs.com/defghy/p/3560895.html
Copyright © 2020-2023  润新知