Javascript 如何使用javascript停止所有超时和间隔?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3141064/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:24:21  来源:igfitidea点击:

How to stop all timeouts and intervals using javascript?

javascript

提问by Calmarius

I'm working on an ajax web appliation which contains many running timeouts and intervals. And now I need to clear all running timeouts and intervals sometimes. Is there a simple way to stop everything without need to store every timeout and interval ID and iterate through them and clear them?

我正在开发一个包含许多运行超时和间隔的 ajax web 应用程序。现在我有时需要清除所有运行超时和间隔。有没有一种简单的方法可以停止一切而无需存储每个超时和间隔 ID 并遍历它们并清除它们?

采纳答案by mplungjan

Updated answer after reading the duplicate I closed this question with -

阅读重复后更新答案我关闭了这个问题 -

It works and tested in Chrome on OSX

它在 OSX 上的 Chrome 中工作和测试

// run something
var id1 = setInterval(function() { console.log("interval", new Date())}, 1000);
var id2 = setTimeout(function()  { console.log("timeout 1", new Date())}, 2000);
var id3 = setTimeout(function()  { console.log("timeout 2", new Date())}, 5000); // not run
          setTimeout(function()  { console.log("timeout 3", new Date())}, 6000); // not run

// this will kill all intervals and timeouts too in 3 seconds. 
// Change 3000 to anything larger than 10

var killId = setTimeout(function() {
  for (var i = killId; i > 0; i--) clearInterval(i)
}, 3000);

console.log(id1, id2, id3, killId); // the IDs set by the function I used

NOTE: Looked at window objects that had a typeof number - funnily enough IE assigns an 8 digit number, FF a single digit starting with 2

注意:查看具有 typeof 数字的窗口对象 - 有趣的是,IE 分配了一个 8 位数字,FF 分配了一个以 2 开头的单个数字

回答by SeanDowney

Sometimes it's possible to save the timer Id / Handle to clear it later which would be the best solution. So this is a second best. But I wanted to give a better understanding of what's going on. It basically grabs the highest timer id and clears everything less than that. But it's also possible to clear other timers that you do not want to clear!

有时可以保存计时器 Id / 句柄以稍后清除它,这将是最好的解决方案。所以这是第二好的。但我想更好地了解正在发生的事情。它基本上会获取最高的计时器 ID,然后清除所有低于该 ID 的内容。但是也可以清除您不想清除的其他计时器!

It is a little hackish, so be warned!

这有点hackish,所以要小心!

// Set a fake timeout to get the highest timeout id
var highestTimeoutId = setTimeout(";");
for (var i = 0 ; i < highestTimeoutId ; i++) {
    clearTimeout(i); 
}

回答by Gokhan Ozturk

Here is a workaround.

这是一个解决方法。

window.timeoutList = new Array();
window.intervalList = new Array();

window.oldSetTimeout = window.setTimeout;
window.oldSetInterval = window.setInterval;
window.oldClearTimeout = window.clearTimeout;
window.oldClearInterval = window.clearInterval;

window.setTimeout = function(code, delay) {
    var retval = window.oldSetTimeout(code, delay);
    window.timeoutList.push(retval);
    return retval;
};
window.clearTimeout = function(id) {
    var ind = window.timeoutList.indexOf(id);
    if(ind >= 0) {
        window.timeoutList.splice(ind, 1);
    }
    var retval = window.oldClearTimeout(id);
    return retval;
};
window.setInterval = function(code, delay) {
    var retval = window.oldSetInterval(code, delay);
    window.intervalList.push(retval);
    return retval;
};
window.clearInterval = function(id) {
    var ind = window.intervalList.indexOf(id);
    if(ind >= 0) {
        window.intervalList.splice(ind, 1);
    }
    var retval = window.oldClearInterval(id);
    return retval;
};
window.clearAllTimeouts = function() {
    for(var i in window.timeoutList) {
        window.oldClearTimeout(window.timeoutList[i]);
    }
    window.timeoutList = new Array();
};
window.clearAllIntervals = function() {
    for(var i in window.intervalList) {
        window.oldClearInterval(window.intervalList[i]);
    }
    window.intervalList = new Array();
};

It works for set/clear timeout/interval functions called after these lines are executed. Try and see it works:

它适用于在执行这些行后调用的设置/清除超时/间隔函数。尝试看看它是否有效:

setInterval('console.log(\'a\')', 1000);
setInterval('console.log(\'b\')', 500);
setInterval('console.log(\'c\')', 750);
setTimeout('clearAllIntervals()', 10000);

Proxying does the magic.

代理有魔力。

回答by Dod

var noofTimeOuts = setTimeout('');
for (var i = 0 ; i < noofTimeOuts ; i++) clearTimeout(i);

回答by KhaledDev

var max = setTimeout(function(){ /* Empty function */ },1);

        for (var i = 1; i <= max ; i++) {
            window.clearInterval(i);
            window.clearTimeout(i);
            if(window.mozCancelAnimationFrame)window.mozCancelAnimationFrame(i); // Firefox
        }

回答by ecmanaut

There's nothing built-in, but it's pretty easy to blast through all currently outstanding deferred execution functions by calling this clearAll()function:

没有任何内置功能,但是通过调用此clearAll()函数可以很容易地浏览所有当前未完成的延迟执行函数:

function clearAll() {
  for (var i = setTimeout(function() {}, 0); i > 0; i--) {
    window.clearInterval(i);
    window.clearTimeout(i);
    if (window.cancelAnimationFrame) window.cancelAnimationFrame(i);
  }
}

If you are in charge of the page you run, and can wrap the native deferred execution functions in wrappers that do the house keeping for of course equip each setter function with a corresponding .clearAll()too:

如果您负责运行的页面,并且可以将本地延迟执行函数包装在包装器中,这些包装器当然会为每个 setter 函数配备相应的.clearAll()

(function(deferFunctions) {
  for (var setter in deferFunctions) (function(setter, clearer) {
    var ids = [];
    var startFn = window[setter];
    var clearFn = window[clearer];

    function clear(id) {
      var index = ids.indexOf(id);
      if (index !== -1) ids.splice(index, 1);
      return clearFn.apply(window, arguments);
    }
    function set() {
      var id = startFn.apply(window, arguments);
      ids.push(id);
      return id;
    }
    set.clearAll = function() { ids.slice(0).forEach(clear); };

    if (startFn && clearFn) {
      window[setter] = set;
      window[clearer] = clear;
    }
  })(setter, deferFunctions[setter]);
})(
{ setTimeout: 'clearTimeout'
, setInterval: 'clearInterval'
, requestAnimationFrame: 'cancelAnimationFrame'
});

To try that it works, you could then try doing this, for instance, which will remain silent, as none of the callbacks end up firing before they're cancelled again:

要尝试它的工作原理,您可以尝试这样做,例如,这将保持沉默,因为在再次取消之前没有任何回调最终触发:

// Some example timers of all types:
requestAnimationFrame(console.error);
setInterval(console.info, 1000, 'interval');
setTimeout(alert, 0, 'timeout');

// Now you can clear all deferred functions
// by execution type, whenever you want to:
window.setTimeout.clearAll();
window.setInterval.clearAll();
window.requestAnimationFrame.clearAll();

回答by shyammakwana.me

A little hack added to Gokhan Ozturk's answer

Gokhan Ozturk 的回答中添加了一个小技巧

If you are using third party libraries which uses Timeoutsand Intervalsthen they will also be cleared, so I added one parameter to notify function that this interval is to be push'ed or not to array.

如果你正在使用的应用第三方库TimeoutsIntervals那么他们也将被清除,所以我加了一个参数通知功能,这个间隔是push“ED或不阵列。

window.setTimeout = function(code, delay, toBeAdded) {
    var retval = window.oldSetTimeout(code, delay);
    var toBeAdded = toBeAdded || false;
    if(toBeAdded) {
        window.timeoutList.push(retval);
    }
    return retval;
};
... // likewise for all functions.

回答by Alan Reitsch

You might be better off creating a scheduler. Take a look at this approach by Nader Zeid:

您最好创建一个调度程序。看看 Nader Zeid 的这种方法:

https://www.onsip.com/blog/avoiding-javascript-settimeout-and-setinterval-problems

https://www.onsip.com/blog/avoiding-javascript-settimeout-and-setinterval-problems

It's an approach that help create some determinacy (because "the time interval argument of each of those functions really only establishes that the given function will execute after at least that amount of time. So a timed event can miss its target by literally any amount of time.").

这是一种有助于创建某些确定性的方法(因为“这些函数中的每一个的时间间隔参数实际上仅确定给定的函数将在至少该时间后执行。因此,定时事件可能会错过任何数量的目标时间。”)。

Specifically, to the question you raise here, you can easily add and remove functions from the queue. While this response is long after the question was raised, hopefully it's helpful to any who find themselves struggling with Timeouts and Intervals.

具体来说,对于您在这里提出的问题,您可以轻松地从队列中添加和删除函数。虽然在提出问题很久之后才做出回应,但希望它对任何发现自己在超时和间隔方面苦苦挣扎的人有所帮助。

回答by Brock Adams

You cannot clear any timeouts and intervals you don't know about.

您无法清除您不知道的任何超时和间隔。

You'd need something like getTimeoutListwhich isn't in the DOM3 spec, or even planned, AFAIK.

你需要的东西getTimeoutList不在 DOM3 规范中,甚至不在计划中,AFAIK。

回答by Bogdan B

The previous proxying trick is nice, but if you have a lot of timeouts and intervals, I would not fill the arrays with consecutive numbers [1,2,3....], but with intervals. For example, instead of having [1,2,3,7,8,9], you would have maybe something like ['1-3','7-9']or [[1,3],[7,9]], as a memory optimization. Of course this trick is only suited if you have a lot of timeouts and intervals and also if you would not stop arbitrary intervals that often.

前面的代理技巧很好,但是如果你有很多超时和间隔,我不会用连续的数字填充数组[1,2,3....],而是用间隔填充数组。例如,作为内存优化[1,2,3,7,8,9],您可能会使用['1-3','7-9']或 之类的东西,而不是[[1,3],[7,9]]。当然,此技巧仅适用于您有很多超时和间隔,并且您不会经常停止任意间隔的情况。