.each and callbacks

I use request modules and cheerio node to create some data from the site. I would like to get a list of items, and as soon as this list is complete, call the 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 to wait for the list to complete, i.e. how can i find out that the .each function is looping on all elements?

Can I do this with async?

thank

+4
source share
3 answers

The .eachcheerio function is synchronous (see source ). Therefore, while you are not doing anything asynchronous in the callback (which is the case in the question), you have nothing to do: in the next line, the loop will be completed.


, Promise.

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

( Q):

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

, Denys Séguret ( .each()) - "" .each(), , , -:

var Promises = require('bluebird');

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

    Promises
    // Use this to iterate serially
    .each($('.myItems').get(), function(el){
        console.log( typeof $(el).text() )
        List.push($(el).text());
    })
    // Use this if order of items is not important
    .map($('.myItems').get(), function(el){
        console.log( typeof $(el).text() )
        List.push($(el).text());
    }, {concurrency:1}) // Control how many items are processed at a time
    // When all of the above are done, following code will be executed
    .then(function(){
        for (var i=0; i <  List.length; i++){
            // make an asynchronous call to a API
        }
    });
});

In this specific code example, it looks like you can make your asynchronous calls inside display functions, but you get the gist ...

Map: https://github.com/petkaantonov/bluebird/blob/master/API.md#mapfunction-mapper--object-options---promise

Each: https://github.com/petkaantonov/bluebird/blob/master/API.md#eachfunction-iterator---promise

+1
source

Source: https://habr.com/ru/post/1540216/


All Articles