Javascript 如何显示setTimeout/setInterval生成的每个运行线程的列表
我想通过纯javascript或浏览器中的任何控制台或其他方式来实现这一点 可能吗 谢谢 进一步解释: 我想调试一个制作动画的库。我想知道如果有多个对象正在设置动画,是否会创建多个计时器。请注意,Javascript 如何显示setTimeout/setInterval生成的每个运行线程的列表,javascript,multithreading,debugging,Javascript,Multithreading,Debugging,我想通过纯javascript或浏览器中的任何控制台或其他方式来实现这一点 可能吗 谢谢 进一步解释: 我想调试一个制作动画的库。我想知道如果有多个对象正在设置动画,是否会创建多个计时器。请注意,setTimeout()不会产生新线程。浏览器端脚本不仅是单线程的,而且JavaScript计算与页面呈现(分开)共享同一个单线程 进一步阅读: 约翰·雷西格 您可能希望自己构建一个计时器管理器: var timerManager = (function () { var timers = [
setTimeout()
不会产生新线程。浏览器端脚本不仅是单线程的,而且JavaScript计算与页面呈现(分开)共享同一个单线程
进一步阅读:
- 约翰·雷西格
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;
}
};
})();
然后按如下方式使用:
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);
上述内容将在控制台中显示以下结果:
// Number of Timers at Start: 2
// Timer t1 triggered after 1 second
// Timer t2 triggered after 5 second
// Number of Timers at End: 0
请注意,上面的
timermager
实现使用了Array.indexOf()
方法。这已添加到JavaScript 1.6中,因此并非所有浏览器都能实现。但是,您可以通过从添加实现轻松地添加方法。正如其他人所提到的,setTimeout
不会产生线程。如果您想要所有超时ID的列表(例如,您可以取消它们),请参见以下内容:
我认为在调用超时ID时,如果不更改代码,就无法获得所有超时ID的列表
setTimeout
返回一个id,如果忽略它,JavaScript将无法访问它。(显然,解释器可以访问它,但您的代码不能访问。)
如果可以更改代码,则可以执行以下操作:
var timeoutId = [];
timeoutId.push(setTimeout(myfunc, 100));
…确保在全局范围内声明timeoutId
(可能通过使用window.timeoutId=[]
)
刚从我脑子里想出来,但要重新实现
setTimeout
,您必须执行以下操作:
var oldSetTimeout = setTimeout;
setTimeout = function (func, delay) {
timeoutId.push(oldSetTimeout(func, delay));
}
这没有经过测试,但它为您提供了一个起点。好主意,莫尔夫
编辑:对上述想法进行了更彻底的实施。最终完成了,这对我来说很有趣,所以我花了一些时间尝试提出一些想法,然后 它覆盖浏览器的
setTimeout
并在窗口中填充当前活动调用的活动状态。_activeSetTimeouts
散列,带有窗口。_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);
if(窗口类型).\u setTimeout==“未定义”){
window.\u setTimeout=window.setTimeout;
窗口。_activeSetTimeouts={};
窗口。_activesettimeouttotal=0;
窗口。_setTimeoutCounter=0;
窗口。_showCurrentSetTimeouts=函数(){
var tgt=document.getElementById(“setTimtoots”);
如果(!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=''u setimtouts';
文件.body.appendChild(tgt);
}
tgt.innerHTML='';
var计数器=0;
用于(窗口中的变量i.\u ActiveSetTimeout){
var li=document.createElement('li');
li.innerHTML='[{status}]{delay}({calltime})
{cb}.f(window.\u activesettimeout[i]);
li.style.background=(计数器+++%2)?“#CCC”:“#EEB”;
tgt.appendChild(li);
}
}
setTimeout=函数(cb,延迟){
变量id=窗口。_setTimeoutCounter++;
var handleId=window.\u设置超时(函数(){
窗口。_activeSetTimeouts[id]。状态为“exec”;
cb();
删除窗口。_activeSetTimeouts[id];
窗口。_activeSetTimeOuttotal--;
},延误);
窗口。\u活动设置超时[id]={
calltime:新日期(),
延迟:延迟,
cb:cb,
状态:'等待'
};
窗口。_activesettimeouttotal++;
返回id;
}
//以下函数用于轻松格式化
String.prototype.f=函数(obj){
var newStr=此+“”;
if(arguments.length==1){
if(类型(obj)=“字符串”){
obj={x:obj};
}
用于(obj中的var i){
newStr=newStr.replace(新的RegExp('{'+i+'}',g'),obj[i]+'';
}
newStr+='';
}否则{
对于(var i=0;iMike,您可以添加更多详细信息吗?您是否只需要运行超时id的列表?javascript不使用线程…您可以重新定义setTimeout()
将ID存储在数组中的某个位置。这样就不需要修改代码,只需在执行之前插入一些Javascript即可。@molf:NICE我将使用decorator模式并连接setTimeout和setInterval函数来查找:)。把你的观点作为答案,这样我就可以接受;)@Mike你通常不需要在动态语言中使用那样复杂的模式。Skilldrick已经用一个例子更新了答案,所以继续接受这个例子。记住你还应该修改setInterval
和clearTimeout
&clearInterval
(从阵列中删除ID)@Skilldrick:我想看看另一个图书馆谢谢我会看看John Resig的文章非常有用,可能是迄今为止我遇到的关于单线程异步事件的最好解释。也谢谢你的优秀代码。有点晚了,但谢谢你的回答,非常有用。不过,我不得不更改cb();
在窗口的第四行调用。setTimeout
:setTimeout中提交的参数可以是函数或某些javascript代码的字符串表示形式。clap…clap…clap…clap…clap clap clap clap clap掌声。太棒了。非常感谢分享!