Reputation: 387
I wrote this function that should run this for loop and then the callback at the end but it keeps running the callback before it finishes the loop. The only solutions I've read said using a callback would fix this issue but it doesn't seem to be making much of a difference.
function run(callback){
for(var i = 0; i < urls.length; i++){
request(url, function(error, resp, body){
//uses cheerio to iterate through some elements on the page
//then saves to an object for a future response
});
callback();
}
}
Upvotes: 0
Views: 958
Reputation: 6791
First of all your code example is missing some brackets. request
is likely an asynchronous library. So at it's function call it's registering with the event loop and returns immediately. Meaning you actually call the callback immediately, probably without request having finished. So synchronously looping with async functions won't work.
Either use something like Promises, Continuation Passing, or register a variable, which tracks whether all calls have returned already.
Upvotes: 0
Reputation: 5636
I would add a variable called totaltasks
and another one called tasksfinished
. Then when a request is finished increment tasksfinished
, and call your callback whenever tasksfinished
equals totaltasks
:
function run(callback){
var totaltasks = urls.length;
var tasksfinished = 0;
// helper function
var check = function() {
if(totaltasks == tasksfinished) {
callback();
}
}
for(var i = 0; i < totaltasks; i++){
try {
request(url, function(error, resp, body) {
tasksfinished++;
check();
});
} catch(e) {
tasksfinished++;
check();
}
}
};
Upvotes: 1
Reputation: 3518
You need to move your callback function inside of the request callback:
function run(callback){
for(var i = 0; i < urls.length; i++){
request(url, function(error, resp, body){
//uses cheerio to iterate through some elements on the page
//then saves to an object for a future response
callback();
});
}
Upvotes: 0