简体   繁体   中英

How to loop in node js, wait until each iteration

I have a function:

var third = function(classes){
  for (var i = 0; i <= (classes.length-1); i++) {
       var Myurl = classes[i];

       return function(Myurl){
          request(Myurl,  function(err, resp, body) { 
             if (!err && resp.statusCode == 200) {
                var $ = cheerio.load(body);
                $("#item_details dl").each(function() {
                   var Values = [];
                   var New = [];

                   Values=$(this).find("dd strong").text();

                   New = Values.replace(/[\n\t\r]/g,"");
                   AllLinks.push(New);
                });

                console.log(AllLinks);
             };
          })
       }(MyUrl);

  };
};

The problem is when I do the above I only get the result of first loop element (i=0) in the console.log(AllLinks) . How do I properly loop in node? I am new to node so any comments are much appreciated!

EDIT: If I define AllLinks in request then it seems to work, but not in correct order...

var third = function(classes){
      for (var i = 0; i <= (classes.length-1); i++) {
           var Myurl = classes[i];

            (function(Myurl){
              request(Myurl,  function(err, resp, body) { 
                 if (!err && resp.statusCode == 200) {
                    var $ = cheerio.load(body);
                    AllLinks=[];
                    $("#item_details dl").each(function() {
                       var Values = [];
                       var New = [];

                       Values=$(this).find("dd strong").text();

                       New = Values.replace(/[\n\t\r]/g,"");
                       AllLinks.push(New);
                    });

                    console.log(AllLinks);
                 }(Myurl);
              })
           };

      };
    };

The major problem (apart from 'return') is that assuming request performs asyncronous operation your function returns when request is not completed and thus log contains no update.

You have two strategies in general:

  1. call your code without 'return' as in the example above. This case all your requests will be eventually done but you have no control over when. It works well when you don't need them all to proceed, eg process AllLinks afterwards
  2. Use any technology that supports waiting until all your calls are completed (async.js or promises). For example here Simplest way to wait some asynchronous tasks complete, in Javascript?

Thus you need:

function appendResultToItems(url, callback) {
 request(url,  function(err, resp, body) { 
   if (!err && resp.statusCode == 200) {
     var $ = cheerio.load(body);
     $("#item_details dl").each(function() {
       var Values = [];
       var New = [];

       Values=$(this).find("dd strong").text();

       New = Values.replace(/[\n\t\r]/g,"");
       AllLinks.push({result:New, url: url});
       callback();
     });
 });
}

var calls = [];

classes.forEach(function(Myurl){
  calls.push(function(callback) {
    appendResultToItems(Myurl, callback);
  });
});

async.parallel(calls, function() {
  console.log(AllLinks);
});

使用async.js #eachSeries将异步函数应用于集合的每个元素

Your problem is you are using return within the loop. If you simply use an IIFE

var third = function(classes){
  for (var i = 0; i <= (classes.length-1); i++) {
       var Myurl = classes[i];

       (function(Myurl){
          request(Myurl,  function(err, resp, body) { 
             if (!err && resp.statusCode == 200) {
                var $ = cheerio.load(body);
                $("#item_details dl").each(function() {
                   var Values = [];
                   var New = [];

                   Values=$(this).find("dd strong").text();

                   New = Values.replace(/[\n\t\r]/g,"");
                   AllLinks.push(New);
                });

                console.log(AllLinks);
             };
          })
       })(MyUrl);

  };
};

AllLinks will be correctly generated.

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