2013-10-01 25 views
0

我在表達式框架中頗爲新穎。我打電話給flickr api獲取專輯列表,每個專輯都需要獲取它的縮略圖。最後需要構建covers陣列,其中包含像{title, thumb}這樣的對象列表。我想通過完全創建covers數組來模板和渲染。我有問題,因爲node.js回調的工作方式和循環在請求結束前快速結束。如何正確地做到這一點?使用asyncrequest爲@sgwilly說,但蹊蹺的結合一系列異步請求來構建最終答案

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

更新...

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

}); 
+1

您是否嘗試過使用[要求](https://npmjs.org/package/request)和[異步](https://npmjs.org/package/async )模塊?他們可以爲你做大部分的繁重工作。 – warchimede

回答

1

Node.js的回調是有點棘手,但一段時間後,他們會是有意義的。

您希望使用request作爲您的外部循環,然後使用async.concat作爲回調內部,並讓每個迭代器都是一個URL請求調用。

+0

非常感謝!這是我一直在尋找的暗示:) – marioosh

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