0

Some issue here;

I've got an HTTP GET call, that runs in an interval every 3 seconds. The call's response data is an array of objects, and I want to log them to the console.

How can I avoid collision between intervals?

An example:

    setInterval(function(){
        $http.get('/some/api').then(function(dataArray){
            dataArray.forEach(function(element){
                  setInterval(function(){
                      console.log(element);
                  },1000)
            });
        })
    },5000)

Assume that the arrays from the api are: [1,2,3] at the first time, and [4,5,6] at the second interval, I need to see: 1 2 3 4 5 6

Thanks

2
  • 1
    Why do you want a 1 second pause between outputting each item return? Why not just output it as you receive it? And the code you have runs every 5 seconds not every 3 seconds. Commented Dec 6, 2016 at 8:25
  • You'd need to stop the inner interval once you're through the array. Commented Dec 12, 2016 at 18:00

2 Answers 2

2

I would want to get away from this nested intervals, other approach what I can think of is to have a array that adds on the data into it from each $http.get('/some/api') call and I will have another function outside of this interval which purely works on the array variable. To be clear let see this sample.

var valuesToLog =[];  // holds the elements 

setInterval(function(){
  $http.get('/some/api').then(function(dataArray){
      valuesToLog.push(dataArray);  //keep adding into the array for logging
  })
},5000)

//new player which runs every second.
setInterval(funcion(){
   if(valuesToLog.length){
     console.log(valuesToLog[0]); //log first item
     valuesToLog.splice(0,1) // and remove the logged item. ie: first item
   }
},1000);

So every second I log the first item in the array and remove it.. Also since the interval is never killed it checks the array every second and if items are present it will log..

Hope this is helpful.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks my friend, its helped my to understand the issue better !
2

Substitute setTimout() for setInterval(); multiply the index of .forEach() callback function by duration 1000

var dataArray = [1, 2, 3];
dataArray.forEach(function(element, index) {
  setTimeout(function() {
    console.log(element);
  }, 1000 * index)
});

You can alternatively call clearInterval() at each successful response, use Promise.all(), Promise() constructor, substitute .map() for .forEach(), call setInterval at .then() chained to Promise.all() when all setTimeout() calls have completed within Promise() constructor

function delay() {
  return $http.get('/some/api').then(function(dataArray) {
    clearInterval(interval);
    return Promise.all(dataArray.map(function(element, index) {
        return new Promise(function(resolve) {
          setTimeout(function() {
            console.log(element);
            resolve();
          }, 1000);
        });
      }))
      .then(function() {
        interval = setInterval(delay, 5000)
      });
  })
}

interval = setInterval(delay, 5000);

function get() {
  return new Promise(function(resolve) {
    resolve(Array.from(Array(Math.floor(Math.random() * 10)).keys()))
  })
}

function delay() {
  return get().then(function(dataArray) {
    clearInterval(interval);
    console.log("current `dataArray.length`:", dataArray.length);
    return Promise.all(dataArray.map(function(element, index) {
        return new Promise(function(resolve) {
          setTimeout(function() {
            console.log(element);
            resolve()
          }, 1000 * index)
        })
      }))
      .then(function() {
        interval = setInterval(delay, 5000)
      });
  })
}

interval = setInterval(delay, 5000)

3 Comments

$http.get('/some/api') called every 5000ms. When 1000 * index > 5000, output will interleave.
@gzc "When 1000 * index > 5000, output will interleave" Original Question describes expected response of array having three elements each "Assume that the arrays from the api are: [1,2,3] at the first time, and [4,5,6] at the second interval". 1000 * index > 5000 should not occur given description at OP. If there are more than three elements returned as response setInteval can be cleared at each response, then called again when .forEach(), setTimeout calls complete.
the array length can be changed.. for example [1,2] and next time [4,7,6,8,3,2] and then [1] ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.