如何停止使用JavaScript的所有超时和间隔?
我正在研究一个包含许多运行超时和间隔的ajax web appliation。 现在我需要清除所有正在运行的超时和间隔。 有没有一种简单的方法来停止一切,而不需要存储每个超时和间隔ID,并遍历它们并清除它们?
阅读完重复后更新了答案我用 – closures了这个问题 –
它在OSX上的Chrome上运行和testing
// 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
有时可以保存定时器Id / Handle来清除它,这将是最好的解决scheme。 所以这是第二好的。 但我想更好地理解发生了什么事情。 它基本上抓住了最高的计时器ID和清除一切比这less。 但是也可以清除其他不想清除的定时器!
这是一个小黑客,所以要警告!
// Set a fake timeout to get the highest timeout id var highestTimeoutId = setTimeout(";"); for (var i = 0 ; i < highestTimeoutId ; i++) { clearTimeout(i); }
这是一个解决方法。
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(); };
它适用于执行这些行后调用的设置/清除超时/间隔函数。 尝试看看它的工作原理:
setInterval('console.log(\'a\')', 1000); setInterval('console.log(\'b\')', 500); setInterval('console.log(\'c\')', 750); setTimeout('clearAllIntervals()', 10000);
代理做魔术。
var noofTimeOuts = setTimeout(''); for (var i = 0 ; i < noofTimeOuts ; i++) clearTimeout(i);
for (var i = 1; i < 99999; i++) { window.clearInterval(i); window.clearTimeout(i); if(window.mozCancelAnimationFrame)window.mozCancelAnimationFrame(i); // Firefox }
没有什么内置的,但通过调用clearAll()
函数可以很容易地通过所有当前优秀的延迟执行函数:
function clearAll() { for (var i = setTimeout(function() {}, 0); i > 0; i--) { window.clearInterval(i); window.clearTimeout(i); if (window.cancelAnimationFrame) window.cancelAnimationFrame(i); } }
如果你负责你运行的页面,并且可以把本地的延迟执行函数包装在做保存的包装器中,当然也可以使用相应的.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' });
为了尝试它的工作,你可以尝试这样做,例如,这将保持沉默,因为没有一个callback结束之前,他们被取消发射:
// 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();
创build一个调度程序可能会更好。 看看Nader Zeid的这个方法:
https://www.onsip.com/blog/avoiding-javascript-settimeout-and-setinterval-problems
这是一种帮助创build一些确定性的方法(因为“每个函数的时间间隔参数实际上只确定了给定的函数在至less该时间之后才会执行”。因此,一个定时事件可能会错过任何数量的时间。”)。
具体来说,对于您在这里提出的问题,您可以轻松地添加和删除队列中的function。 虽然在提出这个问题之后这个回答很长,但是希望对于那些发现自己在超时和间隔方面挣扎的人来说,这是有帮助的。
你不能清除任何你不知道的超时和间隔。
你需要像getTimeoutList
这样的东西,不在DOM3规范,甚至计划,AFAIK。
Gokhan Ozturk的回答中join了一点小窍门
如果你正在使用Timeouts
和Intervals
第三方库,那么他们也将被清除,所以我添加了一个参数来通知函数这个间隔是push
或不是数组。
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.
以前的代理技巧是不错的,但是如果你有很多超时和间隔,我不会用连续的数字[1,2,3....]
填充数组,但是会有间隔。 例如,不是[1,2,3,7,8,9]
,你可能会像['1-3','7-9']
或[[1,3],[7,9]]
,作为内存优化。 当然这个技巧只适用于你有很多超时和间隔的情况,而且如果你经常不停止任意间隔的话。