nodejs async嵌套调用

时间:2014-04-17 12:49:28

标签: javascript node.js asynchronous

我想废弃一个网址:

1获取元素列表的请求

每个结果的1个请求以获取详细信息

我在这里:

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'
});

问题是第二个瀑布函数只运行一次,如果我用each替换eachSeries,循环会运行X次(但我需要等待结果)。

我错过了吗?

1 个答案:

答案 0 :(得分:7)

您需要调用eachSeries callback函数。否则async将不知道你已经完成了。 (1)

您还需要通过调用waterfall函数告诉callback函数您已完成该步骤。 (2)

function (sets, waterfallCallback) {
    async.eachSeries(sets, function (set, seriesCallback) {
        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'));
            });

            seriesCallback(null); /* 1 */

        });
    }, waterfallCallback /* 2 */);
}