【问题标题】:Calling a variable amount of asynchronous functions that are dependent on each other调用可变数量的相互依赖的异步函数
【发布时间】:2017-10-04 17:13:22
【问题描述】:

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

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 案例,它可以在没有警告的情况下终止程序(并占用内存)。

【问题讨论】:

    标签: javascript node.js asynchronous callback


    【解决方案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!');
    });
    

    【讨论】:

    • 有没有办法在不递归的情况下做到这一点? (见编辑)
    • @JacksonDarrow 我想不出没有递归的方法,但是您对堆栈溢出和过多内存使用的担忧是没有根据的。由于调用是异步的,它们不会共享同一个堆栈,而且我的代码编写方式,在任何给定时间,内存中的每个函数最多应该有一次调用。
    【解决方案2】:

    写一个递归函数。

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

    【讨论】:

    • 有没有办法在不递归的情况下做到这一点? (见编辑)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-12
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多