简体   繁体   English

如何防止clearInterval破坏setTimeout

[英]How to prevent clearInterval from breaking setTimeout

I'm a third party javascript developer and one of my clients has the following code on their page, which gets run repeatedly: 我是第三方JavaScript开发人员,我的一位客户的网页上有以下代码,该代码会重复运行:

for (var i = 1; i < 99999; i++) {
    window.clearInterval(i);
}

This of course breaks my setInterval loop. 这当然会破坏我的setInterval循环。 I figured I'd work around that by just using a setTimeout which creates another setTimeout if some conditions aren't met yet. 我认为我可以通过仅使用setTimeout来解决该问题,如果还不满足某些条件,该方法会创建另一个setTimeout Much to my surprise, the clearInterval code above also breaks my timeout. 令我惊讶的是,上面的clearInterval代码打破了我的超时时间。

You can observe this behavior without even creating a setTimeout loop, but just a solitary timer (I wrapped it in some extra code to keep it off the window): 您甚至无需创建setTimeout循环即可观察到此行为,而只是一个单独的计时器(我将其包装在一些额外的代码中以使其不显示在窗口外):

var example = (function(){
  return {
    foo: setTimeout(function(){
      console.log('bar');
    }, 5000)
  };
}());

for (var i = 1; i < 99999; i++) {
    window.clearInterval(i);
}

The only thing I can think to do if overwrite the built in clearInterval to not clear out my timer specifically, but that seems very very wrong and dirty to me. 我唯一想做的事情就是覆盖内置的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);
  }
}

So there is way: place your setTimeout call into an isolated place like a WebWorker or an IFrame , then provide some events to listen on. 因此,有一种方法:将setTimeout调用放置在WebWorkerIFrame之类的隔离位置,然后提供一些事件以供侦听。

I understand it is a hack for just a setTimeout, but a better one then replacing clearInterval. 我知道这只是一个setTimeout的黑客,但最好是取代clearInterval的黑客。

The only way I can think is to play dirty too - redefine window.clearInterval, to ignore clears for your timeout ids: 我能想到的唯一方法就是也玩脏-重新定义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); } 

You could also create a wrapper for setTimeout() to handle adding and removing from the array if you want that part to be neater. 如果希望该部分更整洁,还可以为setTimeout()创建包装器以处理添加和从数组中删除的问题。

It would be interesting to know why they run that ugly piece of code... 知道为什么他们运行那段丑陋的代码会很有趣...

Anyway, your idea to write something uglier is a step in the right direction, but you can push the ugliness a notch, without touching their own function (you're a third party, remember - I'm surprised you even have the right to look at their code). 无论如何,您写出丑陋的东西的想法是朝着正确方向迈出的一步,但是您可以在不影响其自身功能的情况下将丑陋性推高一个等级(您是第三方,请记住-我很惊讶您甚至有权看看他们的代码)。 You won't even have additional id management to do: 您甚至不需要进行其他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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM