如何防止clearInterval破坏setTimeout

时间:2016-02-04 20:41:10

标签: javascript settimeout clearinterval

我是第三方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);
  }
}

3 个答案:

答案 0 :(得分:0)

所以有办法:将你的setTimeout调用放到一个像WebWorkerIFrame这样的隔离的地方,然后提供一些事件来监听。

我知道它只是一个setTimeout的hack,但更好的一个然后替换clearInterval。

答案 1 :(得分:0)

我能想到的唯一方法就是玩脏 - 重新定义window.clearInterval,忽略你的超时ID的清除:

&#13;
&#13;
// 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);
}
&#13;
&#13;
&#13;

如果您希望该部分更整洁,您还可以为setTimeout()创建一个包装器来处理从数组中添加和删除。

答案 2 :(得分:0)

知道为什么他们运行那段难看的代码会很有趣......

无论如何,你写一些丑陋的想法是朝着正确的方向迈出的一步,但你可以将丑陋推向一个档次,而不是触及他们自己的功能(你是第三方,记得 - 我很惊讶你甚至有权在他们的代码中。您甚至不需要额外的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 );
       }
    }
}