ToTa
ToTa

Reputation: 3334

Check if there is active timeout in Javascript

Is there a way to find out if there are active timers ?

I have n-timers with different durations, for example:

Timer 1 -> 2-sec

Timer 2 -> 8-sec

..

...

Timer n -> n-sec

I need to know when all timers are finished

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

Note: I need solution for this particular example because in my project there are n numbers of js files which might have timers that are declared like this example

Upvotes: 13

Views: 10592

Answers (4)

adeneo
adeneo

Reputation: 318242

Here's how I'd do it, create a wrapper around the native functions

(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);

Then use it like

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

Upvotes: 9

Swiffy
Swiffy

Reputation: 4693

I would do this with promises that jQuery offers. Consider this jsfiddle: https://jsfiddle.net/734y1oqy/

First we create an array for the promise objects:

var timers = [];

Then we create the promise objects themselves:

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

Push them to array:

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

Create timers like normal, but have each timer resolve the corresponding promise object:

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);

Create a thing that "watches" when every promise in the promise array is resolved:

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

More info: https://api.jquery.com/category/deferred-object/

Upvotes: 1

cor
cor

Reputation: 3393

You can always add control variables.

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;
});

Upvotes: 3

Parth Trivedi
Parth Trivedi

Reputation: 3832

May be this will help you.

//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
 });

Upvotes: 3

Related Questions