javascript - How to loop in node js, wait until each iteration - Stack Overflow

I have a function:var third = function(classes){for (var i = 0; i <= (classes.length-1); i++) {var M

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

      };
    };

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

      };
    };
Share Improve this question edited May 26, 2015 at 10:39 user1665355 asked May 26, 2015 at 9:58 user1665355user1665355 3,3939 gold badges47 silver badges86 bronze badges 11
  • async library npmjs./package/async – Callum Linington Commented May 26, 2015 at 10:01
  • @CallumLinington Thanks, I am a node beginner, so you maybe can provide an example about how the above function should be changed? best regards – user1665355 Commented May 26, 2015 at 10:02
  • Why do you want to return call result return function(Myurl){...}(MyUrl);? In certain scenarios it might be enough. Otherwise you might want to try promises or async library – Igor Popov Commented May 26, 2015 at 10:03
  • @Igor how do you mean? – user1665355 Commented May 26, 2015 at 10:06
  • I'm not sure how you implement request but if you drop 'return' you'll most likely be able to call all your urls from classes. If you want to wait for all calls to succeed async.js sounds like your choice. – Igor Popov Commented May 26, 2015 at 10:09
 |  Show 6 more ments

3 Answers 3

Reset to default 4

The major problem (apart from 'return') is that assuming request performs asyncronous operation your function returns when request is not pleted 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, e.g. process AllLinks afterwards
  2. Use any technology that supports waiting until all your calls are pleted (async.js or promises). For example here Simplest way to wait some asynchronous tasks plete, 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);
});

Use async.js#eachSeries to apply an asynchronous function to each element of a collection

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.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745205115a4616557.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信