我正在尝试使用nodeJS构建一个web scraper,它在网站的HTML中搜索图像,缓存图像源URL,然后搜索最大尺寸的URL。
我遇到的问题是deliverLargestImage()
在图像源URL数组循环到获取文件大小之前触发。我正在尝试同时使用async.series
和async.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}}
答案 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
函数调用时调用的回调函数 已完成,或发生错误。