如何显示由setTimeout/setInterval生成的每个运行的线程的列表

Mik*_*ier 16 javascript debugging multithreading

我想通过纯JavaScript或浏览器中的任何类型的控制台或其他任何方式来做到这一点.

可能吗?

谢谢

进一步说明:我想调试一个动画库.我想知道如果有多个对象被动画,是否创建了多个计时器.

Dan*_*llo 11

请注意,setTimeout()不会产生新线程.浏览器端脚本不仅是单线程的,而且JavaScript评估与页面呈现共享相同的单个线程(Web Workers除外).

进一步阅读:

您可能想要自己构建一个计时器管理器:

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;
      }
   };
})();
Run Code Online (Sandbox Code Playgroud)

然后使用如下:

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);
Run Code Online (Sandbox Code Playgroud)

以上将在控制台中显示以下结果:

// Number of Timers at Start: 2
// Timer t1 triggered after 1 second
// Timer t2 triggered after 5 second
// Number of Timers at End: 0
Run Code Online (Sandbox Code Playgroud)

请注意,timerManager上面的实现使用了该Array.indexOf()方法.这已在JavaScript 1.6中添加,因此并非所有浏览器都实现.但是,您可以通过添加此Mozilla开发人员中心文章中的实现来自行添加方法 .


aul*_*ron 8

最后完成了,对我来说很有意思,所以我花了一些时间试图想出一些东西,就在这里

它会覆盖浏览器setTimeout并填充window._activeSetTimeouts哈希当前活动调用的活动状态,并使用window._showCurrentSetTimeouts()演示功能显示setTimeout正在等待的当前调用.

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);
Run Code Online (Sandbox Code Playgroud)


Ski*_*ick 6

正如其他人所提到的,setTimeout不会产生一个线程.如果你想要一个所有超时ID的列表(例如你可以取消它们),那么请看下面:


我不认为你可以获得所有超时id的列表,而无需在调用它们时更改代码.setTimeout返回一个id - 如果你忽略它,那么你的JavaScript是不可访问的.(显然解释器可以访问它,但是你的代码没有.)

如果你可以改变代码,你可以这样做:

var timeoutId = [];

timeoutId.push(setTimeout(myfunc, 100));
Run Code Online (Sandbox Code Playgroud)

...确保timeoutId在全局范围内声明(可能通过使用window.timeoutId = []).


只是在我的头顶,但重新实现setTimeout你必须做这样的事情:

var oldSetTimeout = setTimeout;
setTimeout = function (func, delay) {
    timeoutId.push(oldSetTimeout(func, delay));
}
Run Code Online (Sandbox Code Playgroud)

这没有经过测试,但它为您提供了一个起点.好主意,molf!

编辑: aularon的答案给出了更全面的上述想法.

  • 您实际上可以重新定义`setTimeout()`以将ID存储在某个数组中.这样就不需要修改代码了,你只需要在执行之前注入一些Javascript. (3认同)