Stopping Nested Timeouts in Javascript

…衆ロ難τιáo~ 提交于 2019-12-11 06:19:02

问题


I want to execute a piece of arbitrary code and be able to stop it whenever I want. I figured I could do this with setTimeout and then use clearTimeout to stop it. However if the code in the timeout creates it's own timeouts, then those keep executing even after I clear the original.

Example:

var timeoutID = setTimeout(
    function(){
        console.log("first event can be stopped with clearTimout(timeoutID)");
        setTimeout(function(){console.log("but not this one")}, 5000)
    }, 5000)

Now one way would be to control the code being executed and make it store the value of any additional timeouts into a global variable and clear them all at once. But is there a better way to do this? And is there a way to do this on arbitrary code?

To clarify, I'm trying to be able to execute any function I want, then stop it whenever I want, even if the function contains timeouts


回答1:


You can put the inner timeout into a variable too:

var innerTimeout,
    timeoutID = setTimeout(
    function(){
        console.log("first event can be stopped with clearTimout(timeoutID)");
        innerTimeout = setTimeout(function(){console.log("but not this one")}, 5000);
    }, 5000);



回答2:


You would have to create an array of timeout IDs such as this:

var timeoutIds = [];

timeoutIds.push(setTimeout(
  function(){
    console.log("first event can be stopped with clearTimout(timeoutID)");
    timeoutIds.push(setTimeout(function(){console.log("but not this one")}, 5000));
 }, 5000))

And then to clear:

for (int i = 0; i < timeoutIds.length; i++)
{
   clearTimeout(timeoutIds[i]);
}

timeoutIds  = [];



回答3:


You could wrap your timeouts in an object or re use timeoutID for the second timeout.

Wrap in an object:

function Timer(){
  var me=this;
  this.currentTimerID=setTimeout(function(){
    console.log("First timeout");
    me.currentTimerID=setTimeout(function(){
      console.log("Second timeout");
    },100);
  },100);
};
Timer.prototype.cancel=function(){
  clearTimeout(this.currentTimerID);
};

var t = new Timer();//let this run it's course
setTimeout(function(){t = new Timer()},250);//start timer again
setTimeout(function(){t.cancel();},400);// cancel it after the first timeout

Re use timeoutID:

var timeoutID = setTimeout(
    function(){
        console.log("first event can be stopped with clearTimout(timeoutID)");
        timeoutID=setTimeout(function(){console.log("but not this one")}, 100)
    }, 100)
setTimeout(function(){
  clearTimeout(timeoutID);
},150);// will not execute the second timeout

One tip: If you're testing code with timeout then don't use such high values as it'll take 10 seconds for your original code to run.



来源:https://stackoverflow.com/questions/18436465/stopping-nested-timeouts-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!