在javascript中查看所有超时/间隔?

时间:2009-05-13 15:21:29

标签: javascript timeout setinterval

我正在编写一个利用JavaScript超时和间隔来更新页面的应用程序。有没有办法看到设置了多少间隔?我想通过设置数百个间隔来确保我不会意外杀死浏览器。

这甚至是个问题吗?

6 个答案:

答案 0 :(得分:67)

我认为没有办法枚举活动计时器,但你可以覆盖window.setTimeout和window.clearTimeout并用你自己的实现替换它们,这些实现会进行一些跟踪,然后调用原始计时器。

window.originalSetTimeout=window.setTimeout;
window.originalClearTimeout=window.clearTimeout;
window.activeTimers=0;

window.setTimeout=function(func,delay)
{
    window.activeTimers++;
    return window.originalSetTimeout(func,delay);
};

window.clearTimeout=function(timerID)
{
    window.activeTimers--;
    window.originalClearTimeout(timerID);
};

当然,您可能并不总是调用clearTimeout,但这至少会为您提供一些方法来跟踪运行时发生的情况。

答案 1 :(得分:25)

我制作了一个Chrome DevTools扩展程序,显示所有间隔。被清除的人是灰色的。

Timers Chrome Devtool extension

<强> setInterval-sniffer

答案 2 :(得分:10)

看到Paul只覆盖了setTimeout,我以为我会为setInterval / clearInterval共享一个计数器。

window.originalSetInterval = window.setInterval;
window.originalClearInterval = window.clearInterval;
window.activeIntervals = 0;
window.setInterval = function (func, delay)
{
    if(func && delay){
            window.activeIntervals++;
    }
    return window.originalSetInterval(func,delay);
};
window.clearInterval = function (intervalId)
{
    // JQuery sometimes hands in true which doesn't count
    if(intervalId !== true){
        window.activeIntervals--;
    }
    return window.originalClearInterval(intervalId);
};

答案 3 :(得分:8)

这里有一个将所有timerid存储到数组中的实现,而不仅仅是计时器的数量。它仅显示有效计时器,而接受的答案仅计算对setTimeout&amp; clearTimeout

(function(w) {
    var oldST = w.setTimeout;
    var oldSI = w.setInterval;
    var oldCI = w.clearInterval;
    var timers = [];
    w.timers = timers;
    w.setTimeout = function(fn, delay) {
        var id = oldST(function() {
            fn && fn();
            removeTimer(id);
        }, delay);
        timers.push(id);
        return id;
    };
    w.setInterval = function(fn, delay) {
        var id = oldSI(fn, delay);
        timers.push(id);
        return id;
    };
    w.clearInterval = function(id) {
        oldCI(id);
        removeTimer(id);
    };
    w.clearTimeout = w.clearInterval;

    function removeTimer(id) {
        var index = timers.indexOf(id);
        if (index >= 0)
            timers.splice(index, 1);
    }
}(window));

这是您在页面上获得活跃计时器数的方法:

timers.length;

您可以删除所有有效的计时器

for(var i = timers.length; i--;)
    clearInterval(timers[i]);

已知限制:

  • 您只能使用此猴子补丁将函数(不是字符串)传递给setTimeout
  • 该函数假定clearIntervalclearTimeout执行相同操作,但它们可能会在将来更改。

答案 4 :(得分:0)

我只需要这样的东西,这就是我所说的:

window.setInterval = function (window, setInterval) {
    if (!window.timers) {
        window.timers = {};
    }
    if (!window.timers.intervals) {
        window.timers.intervals = {};
    }
    if (!window.timers.intervals.active) {
        window.timers.intervals.active = {};
    }
    return function (func, interval) {
        var id = setInterval(func, interval);
        window.timers.intervals.active[id] = func;
        return id;
    }
}(window, window.setInterval);

window.clearInterval = function (window, clearInterval) {
    if (!window.timers) {
        window.timers = {};
    }
    if (!window.timers.intervals) {
        window.timers.intervals = {};
    }
    if (!window.timers.intervals.inactive) {
        window.timers.intervals.inactive = {};
    }
    return function (id) {
        if (window.timers.intervals.active && window.timers.intervals.active[id]) {
            window.timers.intervals.inactive[id] = window.timers.intervals.active[id];
            clearInterval(id);
            delete window.timers.intervals.active[id];
        }
    }
}(window, window.clearInterval);

记录间隔ID及其功能,并记录其状态(活动/非活动)。

答案 5 :(得分:0)

基于 @Alessio's 答案。下面是我的版本。具有更多的日志记录和检查功能。

以下是一些样板,您可以对其进行更改以使用自己的框架:

var s$ = function (s){return new String(s)}
var _w=window
_w.q$ = {
  getMachineTimeMS: function(){
      var d = new Date(), ms = d.getMilliseconds()
      var a = [d.getHours(), d.getMinutes(), d.getSeconds(), '-', ms<10?'00' + s$(ms):ms<100?'0'+s$(ms):ms]
      return a.join('')
  }
  ,getCaller: function(opts){
      return "(implement this)"
  }
}

主要代码如下:

_w.setTimeout = function (orig_setTimeout) {
  var t=(_w._Timers = _w._Timers||{})
  var d=(t.Timeouts = t.Timeouts||{})
  d.Active = d.Active||{}
  t.z_to_id_idx = t.z_to_id_idx||{}
  return function (h, n) {
    var t = _w._Timers, d = t.Timeouts
    var id = orig_setTimeout(h, n), ts = q$.getMachineTimeMS()
    var c = q$.getCaller({depth:2})
    t.z_to_id_idx[s$(id)] = d.Active[ts] = {sts: ts, id: id, h: h, n: n, scaller: c}
    return id;
  }
}(_w.setTimeout);

_w.clearTimeout = function (orig_clearTimeout) {
  var t=_w._Timers, d = t.Timeouts
  d.Inactive = d.Inactive||{}
  return function new_clearTimeout(id) {
    var t = _w._Timers, d = t.Timeouts, sId = s$(id)
    if (!d.Active || !sId in t.z_to_id_idx) return
    var r = t.z_to_id_idx[sId]
    r.ccaller = q$.getCaller({depth:2})
    r.cts = q$.getMachineTimeMS()
    d.Inactive[r.ts] = r;
    orig_clearTimeout(r.id);
    delete d.Active[r.ts]
    delete t.z_to_id_idx[sId]
  }
}(_w.clearTimeout);

_w.setInterval = function (orig_setInterval) {
  var t=(_w._Timers = _w._Timers||{})
  var d=(t.Intervals = t.Intervals||{})
  d.Active = d.Active||{}
  t.z_in_id_idx = t.z_in_id_idx||{}
  return function (h, n) {
    var t = _w._Timers, d = t.Intervals
    var id = orig_setInterval(h, n), ts = q$.getMachineTimeMS()
    var c = q$.getCaller({depth:2})
    t.z_in_id_idx[s$(id)] = d.Active[ts] = {sts: ts, id: id, h: h, n: n, scaller: c}
    return id;
  }
}(_w.setInterval);

_w.clearInterval = function (orig_clearInterval) {
  var t=_w._Timers, d = t.Intervals
  d.Inactive = d.Inactive||{}
  return function new_clearInterval(id) {
    var t = _w._Timers, d = t.Intervals, sId = s$(id)
    if (!d.Active || !sId in t.z_in_id_idx) return
    var r = t.z_in_id_idx[sId]
    r.ccaller = q$.getCaller({depth:2})
    r.cts = q$.getMachineTimeMS()
    d.Inactive[r.ts] = r;
    orig_clearInterval(r.id);
    delete d.Active[r.ts]
    delete t.z_in_id_idx[sId]
  }
}(_w.clearInterval);

用法示例:

id = setTimeout(()=>{console.log("CALLED")}, 10000)
clearTimeout(id)
setInterval(()=>{console.log("CALLED")}, 1000)

console.table(_w._Timers.Timeouts.Inactive)

console.table 将在 JavaScript 控制台中输出一个格式良好且可检查的表格