[英]How to prevent clearInterval from breaking setTimeout
我是第三方JavaScript開發人員,我的一位客戶的網頁上有以下代碼,該代碼會重復運行:
for (var i = 1; i < 99999; i++) {
window.clearInterval(i);
}
這當然會破壞我的setInterval
循環。 我認為我可以通過僅使用setTimeout
來解決該問題,如果還不滿足某些條件,該方法會創建另一個setTimeout
。 令我驚訝的是,上面的clearInterval
代碼也打破了我的超時時間。
您甚至無需創建setTimeout
循環即可觀察到此行為,而只是一個單獨的計時器(我將其包裝在一些額外的代碼中以使其不顯示在窗口外):
var example = (function(){
return {
foo: setTimeout(function(){
console.log('bar');
}, 5000)
};
}());
for (var i = 1; i < 99999; i++) {
window.clearInterval(i);
}
我唯一想做的事情就是覆蓋內置的clearInterval而不專門清除計時器,但是這對我來說似乎非常錯誤和骯臟。
var originalClearInterval = window.clearInterval;
var exampleLoop = setInterval(function() {
console.log('loop running');
if(typeof window.stopRunning !== 'undefined' && window.stopRunning === true) {
window.clearInterval = originalClearInterval;
clearInterval(exampleLoop);
console.log('loop finished');
}
}, 50);
window.clearInterval = function(timerId) {
if(timerId !== exampleLoop) {
originalClearInterval.apply(this, arguments);
}
}
因此,有一種方法:將setTimeout調用放置在WebWorker
或IFrame
之類的隔離位置,然后提供一些事件以供偵聽。
我知道這只是一個setTimeout的黑客,但最好是取代clearInterval的黑客。
我能想到的唯一方法就是也玩臟-重新定義window.clearInterval,以忽略清除超時ID:
// create an array to store timeout IDs to ignore. window.ignoreTimeoutIds = []; // store original clearInterval function as another property window.clearInterval2 = window.clearInterval; // redefine clearInterval to not clear if it is one of your timeoutIds window.clearInterval = function(intervalId) { if (window.ignoreTimeoutIds.indexOf(intervalId) > -1) console.log('not clearing 1'); // for demo purposes else window.clearInterval2(intervalId); }; (function() { //set the timeout and get its ID var timeoutId = setTimeout(function() { console.log('bar'); // don't forget to remove the timeoutId from the ignore list window.ignoreTimeoutIds.splice(window.ignoreTimeoutIds.indexOf(timeoutId)) }, 5000); // add the timeoutID to the ignore list window.ignoreTimeoutIds.push(timeoutId); }()); for (var i = 1; i < 99999; i++) { window.clearInterval(i); }
如果希望該部分更整潔,還可以為setTimeout()
創建包裝器以處理添加和從數組中刪除的問題。
知道為什么他們運行那段丑陋的代碼會很有趣...
無論如何,您寫出丑陋的東西的想法是朝着正確方向邁出的一步,但是您可以在不影響其自身功能的情況下將丑陋性推高一個等級(您是第三方,請記住-我很驚訝您甚至有權看看他們的代碼)。 您甚至不需要進行其他ID管理:
function setBulletproofTimeout( code, delay ) {
var minId = 99999;
var id = 0;
var myIntervals = [];
for ( var i = 0; i<=minId; i++) {
id = window.setTimeout(code, delay);
if( id >= minId ) {
// that's the One, kill the others
myIntervals.forEach( function( e ) { window.clearInterval( e ); } );
return id;
}
else {
myIntervals.push( id );
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.