Reputation: 303
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
Upvotes: 0
Views: 862
Reputation: 1
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)
Upvotes: 2
Reputation: 18987
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.
Upvotes: 2