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

Posted

技术标签:

【中文标题】查看javascript中的所有超时/间隔?【英文标题】:Viewing all the timeouts/intervals in javascript? 【发布时间】:2010-10-25 21:49:25 【问题描述】:

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

这甚至是个问题吗?

【问题讨论】:

【参考方案1】:

基于@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 控制台中输出格式良好且可检查的表格

【讨论】:

【参考方案2】:

我只是需要这样的东西,这就是我放在一起的东西:

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);

这将记录间隔ids 及其功能,并跟踪其状态 (active/inactive)。

【讨论】:

小心使用整数作为对象索引。在用作 JavaScript 中对象的键之前,最好将整数转换为字符串。这样您就不会使用整数与 JavaScript 的内在索引逻辑发生冲突。这在过去曾经是一个问题。也许它不再是了。【参考方案3】:

我认为没有办法枚举活动计时器,但您可以覆盖 window.setTimeoutwindow.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,但这至少可以为您提供一些方法来跟踪运行时发生的事情。

【讨论】:

我今天在一些代码中使用了它,但是当clearTimeout调用时,我需要activeTimers 递减。这很容易通过将window.setTimeout 的第二行替换为:return window.originalSetTimeout(function() func(); activeTimers--;,delay); 这个答案将不再有效,因为与 DOM 相关的 JavaScript 函数将是“不可变的”。【参考方案4】:

我们刚刚published 一个包解决了这个确切的问题。

npm install time-events-manager

这样,您可以通过timeoutCollection 对象(以及通过intervalCollection 对象的javascript 间隔)查看和管理它们。

timeoutCollection.getScheduled(); timeoutCollection.getCompleted(); timeoutCollection.getAll();

【讨论】:

我认为 OP 和大多数人都在寻找可以在浏览器的控制台中输入的东西作为第一个 PoC,然后可能在扩展中。如何根据您提供的信息将其放入控制台?【参考方案5】:

这里不仅仅是一个计时器计数,而是一个将所有计时器存储到一个数组中的实现。它只显示活动计时器,而接受的答案只计算对setTimeoutclearTimeout 的调用。

(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 执行相同的操作,但它们在未来可能会改变。

【讨论】:

是否可以获得所有正在运行的SetIntervals 的名称?例如var timer = setInterval(function () 我需要 timer 而不是运行间隔计数。 据我所知,我建议使用关键字“setInterval”和/或“setTimeout”进行全局搜索【参考方案6】:

我制作了一个 Chrome DevTools 扩展来显示所有间隔。清除的会变灰。

setInterval-sniffer

【讨论】:

遗憾的是,这似乎停止使用 Chrome。 @JosephLennox 这个替代方案有效,刚刚测试:chrome.google.com/webstore/detail/timeouts-and-intervals/… @Trevor,不幸的是,这似乎也不再适用(使用 Chrome 97)。 如果有人知道这样的实用程序仍然有效,那就太好了。【参考方案7】:

鉴于 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);
;

【讨论】:

以上是关于查看javascript中的所有超时/间隔?的主要内容,如果未能解决你的问题,请参考以下文章

NSMutableURLRequest 超时间隔

javascript:清除所有超时?

未为 iOS 上的 POST 请求设置超时间隔

restkit 0.20.0 中的请求超时

Wildfly 数据源中的空闲超时后未关闭数据库连接

Node中的定时器详解