async.series和async.each无法按预期工作

时间:2014-04-10 20:36:26

标签: javascript node.js asynchronous node-async

我正在尝试使用nodeJS构建一个web scraper,它在网站的HTML中搜索图像,缓存图像源URL,然后搜索最大尺寸的URL。

我遇到的问题是deliverLargestImage()在图像源URL数组循环到获取文件大小之前触发。我正在尝试同时使用async.seriesasync.each来正常工作。

如何强制deliverLargestImage()等待async.each getFileSizes()内的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(); 完成?

JS

{{1}}

1 个答案:

答案 0 :(得分: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接受一个回调作为third parameter,当每个元素的内部循环结束时执行该回调:

  

<强>参数

     
      
  • arr - 要迭代的数组。
  •   
  • iterator(item, callback) - 应用于arr中每个项目的功能。   迭代器传递callback(err),必须在调用后调用   完成。如果没有发生错误,则应在没有错误的情况下运行callback   参数或明确的null参数。
  •   
  • callback(err) - 在所有iterator函数调用时调用的回调函数   已完成,或发生错误。
  •