.each and callbacks

Spearfisher picture Spearfisher · May 12, 2014 · Viewed 11.8k times · Source

I am using request and cheerio node modules to create get some data out of a website. I'd like to get a list of item and once this list is complete, call an asynchronous function:

request('http://myurl', function(req,res,data){
    var $ = cheerio.load(data);
    var List = [];

    $('.myItems').each(function(i, element){
        console.log( typeof $(this).text() )
        List.push($(this).text());
    });

   for (var i=0; i <  List.length; i++){
      // make an asynchronous call to a API
   }
});

My question is how do I wait for the list to be completed, ie, how can I know than the .each function has looped through all the items?

Can I do this with async?

Thanks

Answer

Denys S&#233;guret picture Denys Séguret · May 12, 2014

The .each function of cheerio is synchronous (see source). So as long as you do nothing asynchronous in the callback (which is the case in the question), you have nothing to do : at the following line the loop will be complete.


If you do call asynchronous functions in the loop, the cleanest and simplest solution is to use a Promise library.

In a sequential way (exemple with Bluebird) :

var p = Promise.resolve();
$('.myItems').each(function(i, element){
    p = p.then(function(){ 
         // do something with $(this).text() and return a promise
    });
});
p.then(function(){
   // all asynchronous tasks are finished
});

If sequential requests aren't needed (here an example with Q) :

Q.allSettled($('.myItems').map(function(){
   // return a promise
})).then(function(){
   // all asynchronous tasks are finished
});