Run set Interval again for every interval ID in ar

2019-09-07 13:27发布

问题:

I am currently storing a bunch of setInterval ID's in an array.

How I initially set the intervals:

  intervalId = setInterval(bridgeCall, 10000);
  interValArray.push(intervalId);

I currently have a button that enables me to stop all intervals currently running by calling this function:

  function stopCampaign() {
    if (interValArray.length > 0) {
      for (i = 0; i < interValArray.length; i++) {
        clearInterval(interValArray[i]);
        console.log("Stopped");
      }
      error = "Stopped"
        Error();
    } else {
      error = "Nothing Running"
        Error();
    }
  }

And this works accordingly, So I have tried to do the opposite to start them all back up again as seen below:

  function Campaign() {
    if (interValArray.length > 0) {
      for (i = 0; i < interValArray.length; i++) {
        setInterval(interValArray[i],10000);
        console.log("Start");
      }
      error = "Started"
        Error();
    } else {
      error = "No Agents"
        Error();
    }
  }

But keep getting an error saying:

timers.js:275
    timer._repeat();
          ^

TypeError: timer._repeat is not a function
    at wrapper [as _onTimeout] (timers.js:275:11)
    at Timer.listOnTimeout (timers.js:92:15)

Is it possible to setInterval/Start them up again?

回答1:

You can't use the timer handle to do anything other than cancel the timer. This line:

setInterval(interValArray[i],10000);

tries to "restart" the interval using the handle. That simply isn't supported by the built-in timer stuff. You need to do the same thing you did to start it originally to start it again.

You haven't shown how you start them in the first place, so I can't suggest how you would restructure to make it possible to do it again, but here's a synthetic example:

// Initial setup
var timers = [];
for (var n = 0; n < 5; ++n) {
  startTimer(function(val) {
    document.getElementById("a" + val).innerHTML += ".";
  }.bind(null, n), Math.random() * 1000);
}
function startTimer(f, interval) {
  timers.push({
    f: f,
    interval: interval,
    handle: setInterval(f, interval)
  });
}

// Stop them after three seconds
setTimeout(function() {
  snippet.log("Pausing...");
  timers.forEach(function(timer) {
    clearInterval(timer.handle);
  });
}, 3000);

// Start them two seconds after that
setTimeout(function() {
  snippet.log("Restarting...");
  timers.forEach(function(timer) {
    timer.handle = setInterval(timer.f, timer.interval);
  });
}, 5000);

// Then stop them for good a couple of seconds later
setTimeout(function() {
  snippet.log("Stopping");
  timers.forEach(function(timer) {
    clearInterval(timer.handle);
  });
}, 7000);
<div id="a0">&nbsp;</div>
<div id="a1">&nbsp;</div>
<div id="a2">&nbsp;</div>
<div id="a3">&nbsp;</div>
<div id="a4">&nbsp;</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>



回答2:

The function setInterval(function, interval) returns an ID of the interval, which you already understand as you're storing them in an array.

However, you can't just 'restart' an interval using only its ID. You'd have to clear the interval first, then call setInterval() using the initial parameters used when you stored the items in the array.

You could modify the items in the array to keep all the information necessary to restart the timeouts:

var interValArray = [];

nextTimeout = {
  fn: functionNameToCall,
  interval: 10000,
  id: 0
}

nextTimeout.id = window.setInterval(
  nextTimeout.fn, 
  nextTimeout.interval
)

interValArray.push( nextTimeout )

Your new stopCampaign() would look something like this:

function stopCampaign() {
  if (interValArray.length > 0) {
    for (i = 0; i < interValArray.length; i++) {
      clearInterval(interValArray[i].id);
      console.log("Stopped");
    }
    error = "Stopped"
      Error();
  } else {
    error = "Nothing Running"
      Error();
  }
}

And your new Campaign() would look something like this:

function Campaign() {
  if (interValArray.length > 0) {
    for (i = 0; i < interValArray.length; i++) {
      interValArray[i].id =
        setInterval(interValArray[i].fn,interValArray[i].interval);
      console.log("Start");
    }
    error = "Started"
      Error();
  } else {
    error = "No Agents"
      Error();
  }
}