0

我在快递框架中相当新。我已经调用 flickr api 来获取专辑列表,并且每个专辑都需要获取其缩略图。最后需要covers使用对象列表构建数组,例如{title, thumb}. 我想将完全创建covers的数组传递给模板并渲染。我有问题,因为 node.js 回调的工作方式和for 循环在请求结束之前快速结束。如何正确地做到这一点?

http.get(base_url+'&user_id='+flickr.user_id+'&method=flickr.photosets.getList', function(resp){
    var body = '';
    resp.on('data', function(chunk) {
        body += chunk;
    });
    resp.on('end', function() {
        var json = JSON.parse(body);
        var ps = json.photosets.photoset;

        // final answer
        var covers = {};

        for(var i=0; i<ps.length; i++) {
            var p = ps[i];
            var getSizesUrl = base_url+'&user_id='+flickr.user_id+'&method=flickr.photos.getSizes&photo_id='+p.primary;
            http.get(getSizesUrl, function(resp){
                var body1 = '';
                resp.on('data', function(chunk) {
                    body1 += chunk;
                });
                resp.on('end', function() {
                    var json1 = JSON.parse(body1);
                    covers += {title: p.title._content, thumb: json1.sizes.size[1].source};

                   if(i + 1 == ps.length) {
                        // last call
                        console.log(covers);
                        res.render('photosets', {covers: covers});
                    }
                });
            });
        }
    });
});

正如@sgwilly 所说,使用async和更新,但出了点问题......request

request(base_url+'&user_id='+flickr.user_id+'&method=flickr.photosets.getList', function (error, response, body) {
    var json = JSON.parse(body);
    var ps = json.photosets.photoset;

    // functions list to call by `async`
    var funcs = {};

    for(var i = 0; i < ps.length; i++) {
        var p = ps[i];
        funcs += function(callback) {
            request(base_url+'&user_id='+flickr.user_id+'&method=flickr.photos.getSizes&photo_id='+p.primary, function (error, response, body1){
                var json1 = JSON.parse(body1);
                var cover = {title: p.title._content, thumb: json1.sizes.size[1].source};
                callback(null, cover);
            });         
        };
    }

    // run requests and produce covers
    async.series(funcs,
        function(covers){
            console.log(covers);
            res.render('photosets', {covers: covers});              
        }
    );

});
4

2 回答 2

1

感谢@dankohn。我得到了这个并开始工作:)

request(base_url+'&user_id='+flickr.user_id+'&method=flickr.photosets.getList', function (error, response, body) {
    var json = JSON.parse(body);
    var ps = json.photosets.photoset;

    async.concat(ps, function(p, callback){
        request(base_url+'&user_id='+flickr.user_id+'&method=flickr.photos.getSizes&photo_id='+p.primary, function (error, response, body1){
            var json1 = JSON.parse(body1);
            var cover = {title: p.title._content, thumb: json1.sizes.size[1].source};
            callback(null, cover);
        });         
    }, 
    function(err, covers){
        console.log(covers);
        res.render('photosets', {covers: covers});          
    });
});
于 2013-10-01T13:26:03.437 回答
1

Node.js 回调有点棘手,但过一段时间就会有意义。

您想将request用作外部循环,然后将async.concat作为内部回调,并使每个迭代器成为 URL 的请求调用。

于 2013-10-01T13:17:11.147 回答