99

JavaScript のタイムアウトと間隔を使用してページを更新するアプリケーションを作成しています。設定されている間隔の数を確認する方法はありますか? 何百もの間隔を設定して、誤ってブラウザーを強制終了しないようにしたいと考えています。

これも問題ですか?

4

7 に答える 7

87

アクティブなタイマーを列挙する方法はないと思いますが、それらをオーバーライド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が、これにより、少なくとも実行時に何が起こっているかを追跡する方法が得られます。

于 2009-05-13T15:27:47.527 に答える
30

すべての間隔を表示する Chrome DevTools 拡張機能を作成しました。クリアされたものはグレー表示されます。

タイマー Chrome Devtool 拡張機能

setInterval-スニファー

于 2013-05-23T15:38:16.087 に答える
12

タイマーの数だけではなく、すべての timerid を配列に格納する実装を次に示します。受け入れられた回答は&への呼び出しのみをカウントしますが、アクティブなタイマーのみを表示します。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このモンキー パッチでは、(文字列ではなく) 関数のみを渡すことができます。
  • 関数は同じことを想定clearIntervalしてclearTimeout実行しますが、将来変更される可能性があります。
于 2016-03-11T10:01:59.097 に答える
11

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);
};
于 2011-09-20T15:38:29.463 に答える
0

@Alessioの回答に基づいています。以下は私のバージョンです。ロギングと検査のための機能がもう少しあります。

独自のフレームワークを利用するために変更できる定型文を次に示します。

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 コンソールに出力します。

于 2021-07-10T00:50:45.903 に答える