views:

68

answers:

3

Hi,

I want to do this either by pure javascript or any sort of console in a browser or whatever.

Is it possible?

Thanks

Further explanations: I want to debug a library that does animations. I want to know if there's multiple timers created if there are multiple objects being animated.

+1  A: 

Note that setTimeout() does not spawn new threads. Browser side scripting is not only single threaded, but the JavaScript evaluation shares the same single thread with the page rendering (Web Workers apart).

Further reading:

You may want to build a timer manager yourself:

var timerManager = (function () {
   var timers = [];
   return {
      addTimer: function (callback, timeout) {
         var timer, that = this;
         timer = setTimeout(function () {
            that.removeTimer(timer);
            callback();
         }, timeout);
         timers.push(timer);
         return timer;
      },
      removeTimer: function (timer) {
         clearTimeout(timer);
         timers.splice(timers.indexOf(timer), 1);
      },
      getTimers: function () {
         return timers;
      }
   };
})();

Then use it as follows:

var t1 = timerManager.addTimer(function () {
   console.log('Timer t1 triggered after 1 second');
}, 1000);

var t2 = timerManager.addTimer(function () {
   console.log('Timer t2 triggered after 5 second');
   console.log('Number of Timers at End: ' + timerManager.getTimers().length);
}, 5000);

console.log('Number of Timers at Start: ' + timerManager.getTimers().length);

The above will display the following result in the console:

// Number of Timers at Start: 2
// Timer t1 triggered after 1 second
// Timer t2 triggered after 5 second
// Number of Timers at End: 0

Note that the timerManager implementation above uses the Array.indexOf() method. This has been added in JavaScript 1.6 and therefore not implemented by all browsers. However, you can easily add the method yourself by adding the implementation from this Mozilla Dev Center article.

Daniel Vassallo
Thanks I'll have a look at that
Mike Gleason jr Couturier
+2  A: 

As others have mentioned, setTimeout doesn't spawn a thread. If you want a list of all the timeout ids (so you can cancel them, for example) then see below:


I don't think you can get a list of all timeout ids without changing the code when they are called. setTimeout returns an id, and if you ignore it then it's inaccessible to your JavaScript (obviously the interpreter has access to it, but your code doesn't). If you could change the code you could do this:

var timeoutId = [];

timeoutId.push(setTimeout(myfunc, 100));

making sure that timeoutId is declared in global scope (perhaps by using window.timeoutId = []).


Just off the top of my head, but to reimplement setTimeout you'd have to do something like this:

var oldSetTimeout = setTimeout;
setTimeout = function (func, delay) {
    timeoutId.push(oldSetTimeout(func, delay));
}

This isn't tested, but it gives you a starting point. Good idea molf!

Edit: aularon's answer gives a much more thorough implementation of the above idea.

Skilldrick
You could actually redefine `setTimeout()` to store the ids in an array somewhere. That way no code has to be modified, you just have to inject some Javascript before it is executed.
molf
@molf, how do you do this?
Rocket
@molf good point.
Skilldrick
@molf: NICE I will use the decorator pattern and hook-up the setTimeout and setInterval functions to find out :). Put your point as an anwer so I can accept it ;)
Mike Gleason jr Couturier
@Mike you generally don't need to use complicated patterns like that in dynamic languages.
Skilldrick
molf
@Skilldrick: I want to peek inside another library
Mike Gleason jr Couturier
+1  A: 

Finally done, it was interesting for me so I spent some time trying to come up with something, and here it's

It overrides browser's setTimeout and fill active status of current active calls in window._activeSetTimeouts hash, with window._showCurrentSetTimeouts() demo function that displays current setTimeout calls that are waiting.

if(typeof window._setTimeout =='undefined') {
window._setTimeout=window.setTimeout;

window._activeSetTimeouts={};
window._activeSetTimeoutsTotal=0;
window._setTimeoutCounter=0;
window._showCurrentSetTimeouts=function() {
    var tgt=document.getElementById('_settimtouts');
    if(!tgt) {
    tgt=document.createElement('UL');
    tgt.style.position='absolute';
    tgt.style.border='1px solid #999';
    tgt.style.background='#EEE';
    tgt.style.width='90%';
    tgt.style.height='500px';
    tgt.style.overflow='auto';
    tgt.id='_settimtouts';

    document.body.appendChild(tgt);
    }

    tgt.innerHTML='';
    var counter=0;
    for(var i in window._activeSetTimeouts) {
        var li=document.createElement('LI');
        li.innerHTML='[{status}] {delay} ({calltime})<br /><pre style="width: 100%; height: 5em; overflow: auto; background: {bgcolor}">{cb}</pre>'.f(window._activeSetTimeouts[i]);
        li.style.background=(counter++%2)?'#CCC' : '#EEB';
        tgt.appendChild(li);
    }
}
window.setTimeout=function(cb, delay) {
    var id = window._setTimeoutCounter++;
    var handleId = window._setTimeout(function() {
    window._activeSetTimeouts[id].status='exec';
    cb();
    delete window._activeSetTimeouts[id];
    window._activeSetTimeoutsTotal--;
    }, delay);

    window._activeSetTimeouts[id]={
    calltime:new Date(),
    delay:delay,
    cb:cb,
    status:'wait'
    };
    window._activeSetTimeoutsTotal++;
    return id;
}

//the following function is for easy formatting

String.prototype.f=function(obj) {
var newStr=this+'';
if(arguments.length==1) {
if(typeof(obj)=='string') {
    obj={x:obj};
}


for(var i in obj) {
    newStr=newStr.replace(new RegExp('{'+i+'}', 'g'), obj[i]+'');
}
newStr+='';

} else {
    for(var i=0; i<arguments.length; i++) {
    newStr=newStr.replace('{'+(i+1)+'}', arguments[i]);
    }
}
return newStr;
}
}

//following line for test
for(var i=0; i<5; i++) setTimeout(window._showCurrentSetTimeouts, 3000*i);
aularon
Very good, hats off to you!
Skilldrick