2015-04-26 85 views
2

我不是很習慣nodejs/javascript中的Promise,基本上我希望我的控制器只有在我的承諾完成運行後才返回一個值。Sails.js控制器等待異步服務方法

我在我的Sails應用程序中有以下服務。我正在使用請求承諾模塊向facebook圖形API發出HTTP請求。

return http(options).then(function(data){ 
 

 
     var res = JSON.parse(data); 
 

 
     if(!res || res.error) { 
 
     console.log(!res ? 'error occurred while loading photos' : res.error); 
 
     return; 
 
     } 
 

 
     for (var photoIndex in res.data) { 
 

 
     var photo = res.data[photoIndex]; 
 

 
     if (photo.tags) { 
 

 
      for(var tagIndex in photo.tags.data){ 
 

 
      var tag = photo.tags.data[tagIndex]; 
 

 
      console.log('TAG_ID: '+tag.id + ' -> TARGET_ID: ' + target); 
 

 
      if (tag.id == target) { 
 
       photos.push(photo); 
 
      } 
 

 
      } 
 

 
     } 
 
     } 
 

 
     if (res.paging && res.paging.next) { 
 
     console.log('recursion in action!!'); 
 
     myself(id, target, accessToken, decodeURIComponent(res.paging.next)); 
 
     }

我的控制器:

var countPhotos = Facebook.countTaggedPhotos(requesterId, targetId, accessToken).then(function(photos){ 
 
    return res.json({photos: photos.length}); \t \t \t 
 
});

不過控制器返回0,我的服務承諾結束前,當我看向日誌我可以看到它仍在執行循環。

我怎麼才能讓我的控制器等待一切結束纔回來,我以爲是.then()工作。

回答

2

因爲這個問題,經過幾個小時的撞擊,我找到了問題的根源和解決方案。

根的問題:的遞推

myself(id, target, accessToken, decodeURIComponent(res.paging.next)); 

一旦遞歸開始我沒有得到任何承諾等待他們,導致我的問題,在第一承諾結束,他執行的.then()回調返回數組中的0張照片並釋放控制器以在endind處理其他頁面之前返回。另一個錯誤是我在整個countTaggedPhotos方法中進行遞歸,只改變了http回調。

解決方法:嵌套承諾

var promiseHttp = http(options).then(function myself(data){ 
 

 
    var res = JSON.parse(data); 
 

 
    if(!res || res.error) { 
 
    console.log(!res ? 'error occurred while loading photos' : res.error); 
 
    return; 
 
    } 
 

 
    for (var photoIndex in res.data) { 
 

 
    var photo = res.data[photoIndex]; 
 

 
    if (photo.tags) { 
 

 
     for(var tagIndex in photo.tags.data){ 
 

 
     var tag = photo.tags.data[tagIndex]; 
 

 
     if (tag.id == target) { 
 
      photos.push(photo); 
 
     } 
 

 
     } 
 

 
    } 
 
    } 
 

 
    if (res.paging && res.paging.next) { 
 

 
    var opt={ uri: decodeURIComponent(res.paging.next), method: 'GET' }; 
 
    return http(opt).then(myself); 
 

 
    } 
 

 
}); 
 

 
return promiseHttp.return(photos);

現在我的控制器能夠等待每一頁完成它的處理,並返回正確的照片。

我不知道這個解決方案是否是最好的,但它的工作原理。如果任何人有什麼補充,一些最佳實踐或somenthing,隨時發表評論。

2

當你說這是一個.then()工作時,你是對的。當你說

var countPhotos = Facebook.countTaggedPhotos() 

你設定)countPhotos等於什麼countTaggedPhotos(則()回報。在這種情況下,它不會返回照片的數量。您可以訪問的照片數量唯一的地方在那裏。然後。

爲了進一步幫助您,您需要提供您的周圍

return http(options).then(function(data){... 

,因爲在那裏,你引用的照片的代碼,但我不知道怎麼這實際上是提供給。然後()在你的控制器。