调用相互依赖的可变数量的异步函数

时间:2017-05-06 08:07:22

标签: javascript node.js asynchronous callback

我正在尝试通过网站进行分页,为了请求下一页,需要当前页面上的信息。

function paginateSite(numPages, cb) {
    var stringToGetToNextPage = ''
    for (var i = 0; i < numPages; i++) {
        (function(i, stringToGetToNextPage) {
            request({
                url: 'http://website.com',
                qs: {
                    nextPage: stringToGetToNextPage
                }
            }, 
            function(err, res, body) {
                body_json = JSON.parse(body)
                console.log(body_json.stringToGetToNextPage)
            })
        })(i, stringToGetToNextPage)
    }
}

正如您所看到的,我无法在匿名函数之外设置stringToGetToNextPage。我查看了异步库文档,但无法找到解决我问题的任何内容。

有人遇到过这个问题吗?这似乎是异步范式没有一个干净的解决方案。

编辑:问题#2,可以想象一种没有递归的方法吗?递归适用于小例子,但现在我有一个stackoverflow案例,可以在没有警告的情况下终止程序(并占用内存)。

2 个答案:

答案 0 :(得分:1)

递归就是这样做的方法。

首先,将一个函数分解出来以检索单个页面:

function requestPage(stringToGetToNextPage, callback) {
    request({
        url: 'http://website.com',
        qs: {
            nextPage: stringToGetToNextPage
        }
    }, function(err, res, body) {
        if (err) { callback(err); }
        else { callback(null, JSON.parse(body)); }
    });
}

然后,创建一个可以递归调用自身以获取每个连续页面的函数:

function requestAllPages(stringToGetToNextPage, callback) {
    requestPage(stringToGetToNextPage, function (err, page) {
        if (err) { callback(err); }
        else if (page && page.stringToGetToNextPage) {
            requestAllPages(page.stringToGetToNextPage, callback);
        }
        else { callback(); }
    });
}

然后全力以赴:

requestAllPages(null, function () {
    console.log('Done!');
});

修改如果您确实想要对特定数量的网页进行分页而不是结束,只需对requestAllPages进行少量修改就可以实现这一目标:

function requestPages(numPages, stringToGetToNextPage, callback) {
    if (numPages <= 0) { callback(); return; }

    requestPage(stringToGetToNextPage, function (err, page) {
        if (err) { callback(err); }
        else if (page && page.stringToGetToNextPage) {
            requestPages(numPages - 1, page.stringToGetToNextPage, callback);
        }
        else { callback(); }
    });
}

requestPages(20, null, function () {
    console.log('Done!');
});

答案 1 :(得分:1)

写一个递归函数。

function get_page(next_page_number, last_page_number, string_needed, callback) {

    request(
        {
            url: 'http://website.com',
            qs: {
                nextPage: string_needed
            }
        }, 
        function(err, res, body) {
            // NB: Bad variable name. `body` is JSON. `body_json` won't be.
            var body_json = JSON.parse(body);

            if (next_page_number == last_page_number) {
                callback(body_json);
            } else {
                get_page(
                    next_page_number + 1, 
                    last_page_number,
                    body_json.stringToGetToNextPage,
                    callback
                );
            }
        }
    );

}

get_page(1, 27, "", function (body_json) { console.log(body_json); });