【问题标题】:Check if there is active timeout in Javascript检查Javascript中是否存在活动超时
【发布时间】:2015-12-15 16:33:09
【问题描述】:

有没有办法找出是否有活动的计时器?

我有 n 个不同持续时间的计时器,例如:

Timer 1 -> 2-sec

Timer 2 -> 8-sec

..

...

Timer n -> n-sec

我需要知道所有计时器何时结束

HTML

<div id="time-out-1">
   Time out 1:<span></span>
</div>

<div id="time-out-2">
   Time out 2:<span></span>
</div>

<button>
   Are all timers finished ?
</button>

JS

setTimeout(function () {
        $("#time-out-1 span").text("Finished !");
 },2000);


  setTimeout(function () {
        $("#time-out-2 span").text("Finished !");
 },8000);

 $('button').click(function(){
        // if all timers are finished
        // do something
 });

Jsfidle

注意:我需要这个特定示例的解决方案,因为在我的项目中有 n 个 js 文件,这些文件可能具有像这个示例一样声明的计时器

【问题讨论】:

  • 我不相信可以通过对它的引用来确定计时器是否处于活动状态,因为引用只是一个没有属性的整数。如果您可以提供您希望实现的目标的详细信息,我们或许可以提出替代方案。
  • 如果您的超时没有交错/延迟,您是否只需要检查一下是否发生了 最长 超时?在这种情况下,您可以只根据它切换一个布尔值。
  • @Quantastical 可能会给出意想不到的结果ejohn.org/blog/how-javascript-timers-work
  • 那么,如果这些计时器是从第三方代码设置的,您将不得不重写 setTimeout()/clearTimeout() 方法来跟踪任何正在运行的计时器,恕我直言,您真的不想做任何事情......看起来真的就像一个 XY 问题,但我可能是错的

标签: javascript jquery settimeout


【解决方案1】:

我会这样做,围绕原生函数创建一个包装器

(function(w) {
     var active = {};

     var _setTimeout = w.setTimeout;
     var _clearTimeout = w.clearTimeout;

     w.setTimeout = function(fn, delay) {
         var id = _setTimeout(function() {
             fn();
             delete active[id];
         }, delay);
         active[id] = true;
         return id;
     }

     w.clearTimeout = function(id) {
         delete active[id];
         _clearTimeout(id);
     }

     w.activeTimers = function() {
         return Object.keys(active).length > 0;
     }
})(window);

然后像这样使用它

setTimeout(function () {
    $("#time-out-1 span").text("Finished !");
},2000);


setTimeout(function () {
    $("#time-out-2 span").text("Finished !");
},8000);

$('button').click(function(){
    if ( window.activeTimers() ) {
        // still something going on
    } else {
        // all done !
    }
});

FIDDLE

【讨论】:

    【解决方案2】:

    也许这会对你有所帮助。

    //if n Timer then take count n
    var count = 2;
    
    setTimeout(function () {
            count--;
            $("#time-out-1 span").text("Finished !");
     },2000);
    
    
      setTimeout(function () {
            count--;
            $("#time-out-2 span").text("Finished !");
     },8000);
    
     $('button').click(function(){
            //Check if all Timers are finished
            if(count==0)
            //finished
     });
    

    【讨论】:

      【解决方案3】:

      您始终可以添加控制变量。

      var timer1_active = true,
          timer2_active = true;
      setTimeout(function () {
          timer1_active = false;
          $("#time-out-1 span").text("Finished !");
      },2000);
      
      
      setTimeout(function () {
          timer2_active = false;
          $("#time-out-2 span").text("Finished !");
      },8000);
      
      $('button').click(function(){
          //Check if all Timers are finished
          var finished = !timer1_active && !timer2_active;
      });
      

      【讨论】:

      • 等等,为什么它被否决了???看起来像有效的解决方法,也许不是最好但有效
      【解决方案4】:

      我会用 jQuery 提供的promises 来做这件事。考虑这个 jsfiddle:https://jsfiddle.net/734y1oqy/

      首先我们为promise objects创建一个数组:

      var timers = [];
      

      然后我们自己创建promise objects

      var timer1promise = $.Deferred();
      var timer2promise = $.Deferred();
      var timer3promise = $.Deferred();
      

      将它们推入数组:

      timers.push(timer1promise);
      timers.push(timer2promise);
      timers.push(timer3promise);
      

      像平常一样创建计时器,但让每个计时器解析相应的承诺对象:

      var timer1 = setTimeout(function() { console.log('timer 1 finished'); timer1promise.resolve(); }, 1000);
      var timer2 = setTimeout(function() { console.log('timer 2 finished'); timer2promise.resolve(); }, 2000);
      var timer3 = setTimeout(function() { console.log('timer 3 finished'); timer3promise.resolve(); }, 3000);
      

      当 Promise 数组中的每个 Promise 都被解决时,创建一个“监视”的东西:

      $.when.apply($, timers).then(function()
      {
          console.log('All timers done!');
      });
      

      更多信息:https://api.jquery.com/category/deferred-object/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-13
        • 2023-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多