2014-04-10 81 views
1

我正在嘗試使用nodeJS構建一個網絡抓取工具,該工具會搜索網站的HTML圖像,緩存圖像源URL,然後搜索最大尺寸的網址。async.series和async.each不能按預期工作

我遇到的問題是deliverLargestImage()在映像源URL數組循環以獲取其文件大小之前正在觸發。我試圖同時使用async.seriesasync.each來正確地工作。

我該如何強制deliverLargestImage()等到裏面的async.each完成?

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

'getFileSizes()'不等待內部'async.each'完成,但立即觸發'callback()'... –

回答

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功能 已完成或發生錯誤時調用的回調。