async.series和async.each不按预期方式工作
我正在尝试使用nodeJS构build一个网页抓取工具,该工具会search网站的HTML图像,caching图像源URL,然后search最大尺寸的url。
我遇到的问题是,在图像源URL数组循环以获取文件大小之前, deliverLargestImage()
正在触发。 我正在尝试使用async.series
和async.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函数。