1

Web サイトの HTML で画像を検索し、画像ソース URL をキャッシュしてから、最大サイズのものを検索する nodeJS を使用して Web スクレーパーを構築しようとしています。

私が抱えている問題はdeliverLargestImage()、画像ソース URL の配列がファイル サイズを取得するためにループされる前に発生することです。私は両方を使用して、これを適切に機能させようasync.seriesasync.eachしています。

内部が完成deliverLargestImage()するまで強制的に待機するにはどうすればよいですか?async.eachgetFileSizes()

JS

var async, request, cheerio, gm;
async = require('async');
request = require('request');
cheerio = require('cheerio');
gm = require('gm').subClass({ imageMagick: true });

function imageScraper () {
  var imgSources, largestImage;
  imgSources = [];
  largestImage = {
    url: '',
    size: 0
  };

  async.series([
    function getImageUrls (callback) {
      request('http://www.example.com/', function (error, response, html) {
        if (!error && response.statusCode === 200) {
          var $ = cheerio.load(html);
          $('img').each(function (i, elem) {
            if ( $(this).attr('src').indexOf('http://') > -1 ) {
              var src = $(this).attr('src');
              imgSources.push(src);
            }
          });
        }
        callback();
      });
    },
    function getFileSizes (callback) {
      async.each(imgSources, function (img, _callback) {
        gm(img).filesize(function (err, value) {
          checkSize(img, value);
          _callback();
        });
      });
      callback();
    },
    function deliverLargestImage (callback) {
      callback();
      return largestImage;
    }
  ]);

  function checkSize (imgUrl, value) {
    var r, raw;
    if (value !== undefined) {
      r = /\d+/;
      raw = value.match(r)[0];
      if (raw >= largestImage.size) {
        largestImage.url = imgUrl;
        largestImage.size = raw;
      }
    }
  }
}

imageScraper();
4

1 に答える 1

2

ここに移動してみてくださいcallback()

function getFileSizes (callback) {
  async.each(imgSources, function (img, _callback) {
    gm(img).filesize(function (err, value) {
      checkSize(img, value);
      _callback();
    });
  }, function(err){ callback(err); }); /* <-- put here */
  /* callback(); <-- wrong here */
},

each各要素の内側のループが終了したときに実行される3 番目のパラメーターとして、コールバックを受け入れます。

引数

  • arr- 反復する配列。
  • iterator(item, callback)- の各項目に適用する関数arr。イテレータには a が渡され、callback(err)完了後に呼び出す必要があります。エラーが発生していない場合は、callback引数なしで、または明示的なnull引数を指定して を実行する必要があります。
  • callback(err)iterator- すべての関数が終了したとき、またはエラーが発生したときに呼び出されるコールバック。
于 2014-04-10T20:43:54.787 に答える