• 使用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左右.这个与电脑硬件有关系.所以使用定时器来达到一些精准的任务并不是一个最好的选择.



    参考

  • 相关阅读:
    C++同步串口通信
    python描述符详解
    python属性访问
    python简单计时器实现
    python时间模块详解(time模块)
    python魔法方法大全
    python类与对象各个算数运算魔法方法总结
    python里的魔法方法1(构造与析构)
    Python 函数修饰符(装饰器)的使用
    python类与对象的内置函数大全(BIF)
  • 原文地址:https://www.cnblogs.com/gtscool/p/14284524.html
Copyright © 2020-2023  润新知