2014-04-17 7 views
4

나는 URL을 스크랩하고 싶은nodejs 비동기 중첩 호출

var request = require('request') 
    , cheerio = require('cheerio') 
    , async = require('async') 
    , format = require('util').format; 

var baseurl = 'http://magiccards.info'; 
async.waterfall([ 
    function (callback) { 
     request(baseurl + '/sitemap.html', function (err, response, body) { 
      var sets = []; 
      var $ = cheerio.load(body); 
      $('a[href$="/en.html"]').each(function() { 
       sets.push({"name": $(this).text(), "code":$(this).attr('href').match(/\/([^)]+)\//)[1], "path": $(this).attr('href'), "translations":[]}); 
      }); 
      callback(null, sets); 
     }); 
    }, 
    function (sets, callback) { 
     console.log(sets); 
     async.eachSeries(sets, function (set, callback) { 
      console.log('SET ' + set.code.toUpperCase()); 
      request(baseurl + set.path, function (err, response, body) { 
       var $ = cheerio.load(body); 
       $('body > a[href^="/' + set.code + '/"]').each(function() { 
        console.log(' %s (%s)', $(this).text(), $(this).attr('href')); 
       }); 
      }); 
     }); 
    } 
], function (err, result) { 
    console.log('ERR'); 
    // result now equals 'done' 
}); 

문제는 두 번째 폭포 함수가 한 번만 실행된다는 것입니다. 각Series를 각각으로 교체하면 루프가 X 번 실행되지만 결과는 기다려야합니다.

내가 실종 됐어?

답변

7

eachSeriescallback 함수를 호출해야합니다. 그렇지 않으면 async이 완료되었음을 알 수 없습니다. (1)

또한 waterfall 함수에서 해당 단계를 완료했음을 알리고 callback 함수를 호출해야합니다. (2)

+0

잘 작동하지만 두 번째 콜백이 필요하지 않습니다. (왜 콜백을 사용합니까?) 각 시리즈에 콜백을 넣을 때 콜백이 정의되지 않았다는 것을 알 수 있습니다 (함수 없음) – kitensei

+0

두 개의 다른 콜백을보다 잘 설명하기 위해 해답을 수정했습니다. 두 번째 기능이 없으면 마지막 기능이 실행되지 않습니다. ('console.log ('ERR');와'// 결과는 이제'done''과 같음) –