I am making a function that refreshes data every so often and I am having issues with the request chain that I have. The problem is that I have a for-loop running the asynchronous requests and the for-loop will finish before the requests are done.
setInterval(function(){ // this updates the total hours of all members every 10 seconds
request({ // this gets all of the loyalty program members
url: "",//omitted
method: "GET"
},
function(listError, listResponse, listBody) {
if(listError == null && listResponse.statusCode == 200) {
var varBody = {};
var listObj = JSON.parse(listBody);
for(var i = 0; i < listObj.result.length; i++) { // parses through all of the members to update their hours
console.log(i);//****PRINT STATEMENT
varBody.index = i;
varBody.memberID = listObj.result[i].program_member.id;
request({ //we do this request to get the steam ID of the program member
url: "",//omitted
method: "GET"
},
function(fanError, fanResponse, fanBody) {
var fan = JSON.parse(fanBody);
if(fanError == null && fanResponse.statusCode == 200 && fan.result.profiles.length != 0) { // make sure that the profile isn't empty
request({
url:"",//omitted
method: "GET"
},
function(hourError, hourResponse, hourBody) {
if (hourError == null && hourResponse.statusCode == 200) {
var gameList = JSON.parse(hourBody);
var minutes = 0;
for (var j = 0; j < gameList.response.games.length; j++) { // for loop to calculate the minutes each user has on steam
minutes += gameList.response.games[j].playtime_forever;
}
var deltaHours = 1;
if(deltaHours != 0) {
var transaction = { // updated member object to be inserted
pointsearned: deltaHours,
pointsused: 0,
loyaltyprogram_id: loyaltyID,
programmember_id: memberID
};
request({ // POST request to update the member
url: "",//omitted
method: "POST",
body: JSON.stringify(transaction),
headers: {
"Content-Type": "application/json"
}
},
function(updateError, updateRes, updateBody) {
if(updateError == null && updateRes.statusCode == 200) {
console.log("Success");//****PRINT STATEMENT
}
}
);
}
}
}
);
}
}
);
}
}
console.log("Users Updated"); //****PRINT STATEMENT
}
);
}, 10000);
If I were to run this code, it would print:
0
1
2
3
Success
Success
Success
Success
I know what the issue is. It's the fact that the for-loop doesn't wait for the requests to finish. What I don't know is a work-around for this. Does anyone have any ideas?
For completeness, the way to do async things sequentially "by hand" is to use recursion:
function dothings(things, ondone){
function go(i){
if (i >= things.length) {
ondone();
} else {
dothing(things[i], function(result){
return go(i+1);
});
}
}
go(0);
}