async.series和async.each不按预期方式工作

我正在尝试使用nodeJS构build一个网页抓取工具,该工具会search网站的HTML图像,caching图像源URL,然后search最大尺寸的url。

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

如何强制deliverLargestImage()等待getFileSizes()内部的getFileSizes()完成?

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(); 

尝试移动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接受一个callback作为第三个参数 ,当每个元素的内部循环完成时执行:

参数

  • arr – 要迭代的数组。
  • iterator(item, callback) – 应用于arr每个项目的函数。 迭代器被传递一个callback(err)函数callback(err) ,一旦它完成,就必须被调用。 如果没有错误发生, callback应该运行没有参数或显式的null参数。
  • callback(err) – 当所有iterator函数完成或发生错误时调用的callback函数。