简体   繁体   中英

Node.js res.render when task completed

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.

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 });
});

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".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM