0

我有下面的代码,并在_.each函数完成后尝试访问all_records数组。但是,由于它是异步的,我想知道是否可以将回调强制到每个下划线?

var request = require('request'),
    cheerio = require('cheerio'),
    _       = require('underscore');

var all_records = [];

_.each([0,100], function(start) {

  var base_url = "http://www.example.com/search?limit=100&q=foobar&start=";
  var url = base_url + start;

  request(url, function(err, res, body) {
    var $ = cheerio.load(body),
      links = $('#results .row');
    $(links).each(function(i, link) {
      var $link = $(link);
      var record = {
        title: $link.children('.title').text().trim()
      };
      all_records.push(record);
    });
  });
});

// Need to run this once _.each has completed final iteration.
console.log(all_records);
4

2 回答 2

2

这是使用简单同步方法的简单解决方案:

var count = 101;//there are 101 numbers between 0 and 100 including 0 and 100
_.each([0,100], function(start) {

  var base_url = "http://www.example.com/search?limit=100&q=foobar&start=";
  var url = base_url + start;

  request(url, function(err, res, body) {
    var $ = cheerio.load(body),
      links = $('#results .row');
    $(links).each(function(i, link) {
      var $link = $(link);
      var record = {
        title: $link.children('.title').text().trim()
      };
      all_records.push(record);
      count--;
      if(count===0){//101 iterations done
         console.log(all_records);
      }
    });
  });
});

使用async's.parallel方法可以实现更优雅的解决方案。

var requests = []; //an array for all the requests we will be making

for(var i=0;i<=100;i++){
   requests.push((function(done){ //create all the requests
       //here you put the code for a single request. 
       //After the push to all_records you make a single done() call 
       //to let async know the function completed
   }).bind(null,i));//the bind is that so each function gets its own value of i   
}
async.parallel(requests,function(){
    console.log(all_records);
});
于 2013-03-30T17:02:28.033 回答
0

async.each最终成为最容易实现的。

async.each([0,100], function(start) {
  var base_url = "http://www.example.com/search?limit=100&q=foobar&start=";
  var url = base_url + start;

  request(url, function(err, res, body) {
    var $ = cheerio.load(body),
      links = $('#results .row');
    $(links).each(function(i, link) {
      var $link = $(link);
      var record = {
        title: $link.children('.title').text().trim()
      };
      all_records.push(record);
    });
  });
}, function(err){
  console.log(all_records);
});
于 2013-03-30T19:41:17.097 回答