How can I show a list of every thread running spawned by setTimeout/setInterval

后端 未结 3 679
悲&欢浪女
悲&欢浪女 2021-02-01 22:11

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

相关标签:
3条回答
  • 2021-02-01 22:30

    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:

    • How JavaScript Timers Work by John Resig

    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.

    0 讨论(0)
  • 2021-02-01 22:32

    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.

    0 讨论(0)
  • 2021-02-01 22:33

    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);
    
    0 讨论(0)
提交回复
热议问题