zoukankan      html  css  js  c++  java
  • 使用SetTimeout模拟/模仿SetInterVal(JavaScript)

    问题背景

      近日我在开发一个答题小程序的时候,需要判断用户在规定答题时间内完成所有答题。但是,遇到了一个问题是使用setInterval(func,time)的时候。担心会遇到一些问题。造成这个担心的原因是因为之前开发VUE单页应用的时候.从别的选项卡切换当前网页选项卡的时候.当前网页的倒计时会一度变得不如预期所想的那样(1s变一下数字)。而是倒计时的速度变得非常快。
      于是,网上查到了如何使用setTimeOut()来模拟setInterVal()

    代码

         var timer;
         var i = 1;
         timer = function () {
             i++;
             console.log(i);
             if (i == 10) {
                 timer = function () {
                     console.log("终止运行");
                 }
             }
             setTimeout(timer, 500);
         };
         console.log(timer);
         setTimeout(timer, 500);
    

      刚开始理解这段代码的时候,我有点不知所以然.但是现在觉得是非常容易理解的.在这段函数是timer指向了一个内存空间的对象的引用(这个对象可以执行一些动作,它就是函数).
    setTimeout会在倒计时结束之后去回调这个函数.而在回调这个函数到函数执行体内的时候,又会去设置一个定时器.这个定时器的回调函数指向了一个内存空间的引用.这还是Timer.所以它会起到模拟setInterval的效果.
      同时,这种写法也是更为可控的.
      如何取消这个定时器.只需要把timer设置为别的值,或者指向别的引用就可以了.

     timer = function () {
        console.log("终止运行");
        }
    

    以下是一种函数的写法

    let timer = null;
    interval(func, wait){
        let interv = function(){
            func.call(null);
            timer=setTimeout(interv, wait);
        };
        timer= setTimeout(interv, wait);
     },
    
    interval(function() {}, 20);
    
    

    在Vue2.x中,需要将timer定义在data属性中,比如说timer=function(){}.[JS变量类型的转换会额外消耗性能].清除定时器需要使用this.timer.

    需要注意的是定时器并不是严格按照预期时间去执行的.它可能提前或者延迟执行.这和Javascript的语言特性有关.众所周知JavaScript是单线程语言.JavaScript的多线程和异步是依靠于EventLoop(事件循环)机制来进行实现的.语言特性决定了定时器总是趋近于设定时间去执行的.

          setTimeout(function () {
                console.log("等等我呀");
                console.timeEnd('caltime');
            }, 1000);
            console.log('我先执行咯');
            console.time('caltime');
    
    
            // 以下代码仅用于消耗调用栈的执行时间
            var speedTime = [];
            for (var i = 0; i < 100000000; i++) {
                speedTime.push(i);
            }
    
    

    以上代码经过实际测试会发现,定时器的调用间隔不是1s.我这里经过测试是2s左右.这个与电脑硬件有关系.所以使用定时器来达到一些精准的任务并不是一个最好的选择.



    参考

  • 相关阅读:
    。。
    6-4 静态内部类
    SQL把一个表里的数据赋值到另外一个表里去
    jquery 设置 disabled属性
    6-4 内部类
    DWR 整合之Struts2.3.16
    DWR整合之JSF
    DWR整合之Servlet
    dwr.xml 配置
    认识DWR
  • 原文地址:https://www.cnblogs.com/gtscool/p/14284524.html
Copyright © 2011-2022 走看看