Reputation: 7628
I'm making Node.js Application using Express.js. I have a page which render some datas from other site. so I use with Cheerio.js and It's not problem, but the problem is I don't know how can I render when the scrapping task completed. I made a code like below, Please see.
var urls = [ 'http://a.com/fruits', 'http://a.com/cars', 'http://a.com/toys' ]
function getData(){
// get html and parse, return some data.
...
}
var data_set = '';
for (var i=0; i< urls.length ; i++){
data_set += getData(urls[i]);
}
// When get all data, render <------ How can I catch when?
res.render('some_page', { data : data_set });
Thought some ways to do it,
#1 - Render when i == urls.length
for (var i=0; i< urls.length ; i++){
data_set += getData(urls[i]);
if( i == urls.length){
res.render(....);
}
}
// Result :
// The data has not been scrapped, so the page wouldn't display data fully.
#2 - callback with getData()
function getData(callback){
// get html and parse, return some data.
...
// when complete, callback();
}
var someHelper = 0;
getData(function(){ someHelper ++ ;});
if (someHelper == 3){
res.render(...);
}
// If someHeper is not 3, the page would not rendered.
// And `if statement` executed before someHelper == 3 at times ==> infinite page loading (error)
How can I handle this? Should I find use Promise
?...
Please Help me with some points.
Upvotes: 0
Views: 1657
Reputation: 1
Nested callbacks may help you. You can call the getData function one by one, and append content to data_set in each callback function.
var urls = [ 'http://a.com/fruits', 'http://a.com/cars', 'http://a.com/toys' ], data_set = '';
function getData(url, cb){
// get html and parse, return some data.
...
// call cb when downloaded contents
cb(content);
}
getData(urls[0], function (content) {
data_set += content;
getData(urls[1], function (content) {
data_set += content;
getData(urls[2], function (content) {
data_set += content;
res.render('some_page', { data : data_set });
}
}
});
To avoid callback hell, you can also use module like "async", "q", "promise".
Upvotes: 0
Reputation: 5376
you should use either promises or async.js library up to you really...
here is how you could do it using promises
function getData(urlString) {
return new Promise(function (res, rej) {
//fetch and resolve promise with data from urlString
});
}
var data_set = '';
var promises = [];
for (var i=0; i< urls.length ; i++){
promises.push(function () {
return getData(urls[i]).then(function (data) {
data_set += data;
});
});
}
Promise.all(promises).then(function () {
res.render('some_page', { data : data_set });
});
Upvotes: 2