Reputation: 16142
Here is the part of my code that's not working:
var companiesUrls = [];
var companiesUrls2 = [];
request(site+companiesPath, function(err, resp, body){
if(!err && resp.statusCode == 200){
var $ = cheerio.load(body);
$('a', '#group-content').each(function(){
var url = $(this).attr('href');
companiesUrls.push(url);
});
console.log(companiesUrls.length);
}
});
console.log(companiesUrls);
for(var i=0;i<companiesUrls.length;i+=2){
companiesUrls2.push(companiesUrls[i]);
};
console.log(companiesUrls2);
Here is the output that this code yields:
[]
[]
102
My theory is that node.js's "non-blocking" nature is causing the request to run after the rest of the code. And because of that my for loop gets the empty array instead of array that holds 102 items in it.
How can I fix that?
Upvotes: 2
Views: 79
Reputation: 10202
var companiesUrls = [];
var companiesUrls2 = [];
request(site+companiesPath, function(err, resp, body){
if(!err && resp.statusCode == 200){
var $ = cheerio.load(body);
$('a', '#group-content').each(function(){
var url = $(this).attr('href');
companiesUrls.push(url);
});
console.log(companiesUrls.length);
}
console.log(companiesUrls);
for(var i=0;i<companiesUrls.length;i+=2){
companiesUrls2.push(companiesUrls[i]);
};
console.log(companiesUrls2);
});
Alright, simple enough. But what if that code needs to run within a function? The common solution to this is to provide a callback as the function's parameter. It is common for node code to use callbacks frequently, as this is typically the best approach from a performance standpoint.
function getCompanyUrls(callback) {
var companiesUrls = [];
var companiesUrls2 = [];
request(site+companiesPath, function(err, resp, body){
if(!err && resp.statusCode == 200){
var $ = cheerio.load(body);
$('a', '#group-content').each(function(){
var url = $(this).attr('href');
companiesUrls.push(url);
});
console.log(companiesUrls.length);
}
console.log(companiesUrls);
for(var i=0;i<companiesUrls.length;i+=2){
companiesUrls2.push(companiesUrls[i]);
};
console.log(companiesUrls2);
callback(companiesUrls2);
});
}
getCompanyUrls(function( urls ) {
// do something with the resulting urls.
});
Upvotes: 3