2015-06-04 70 views
1

我得到了兩個循環,用戶的外部循環和內部的循環遍歷每個用戶的場所ID。在內部循環中,我想查找場地並將其附加到在外觀中定義的陣列(userItem)。但是,因爲forEach是同步的,並且mongo數據庫查找是異步的,所以結果始終爲空。我試圖整合this answer但無濟於事。這個怎麼做?在內部forEach循環中集成異步mongo調用

ret = []; 
users.forEach(function(user) { 
    var userItem = user.getSanitised('ADM'); 

    userItem.venues = []; 

    var tmp = []; 

    userItem.adminVenueIds.forEach(function(adminVenueId){ 
     tmp.push(function(callback) { 

      Venue.findOne({_id:adminVenueId}, function(error, venue) { 

       callback(null, venue.toObject()); 
      }); 
     }); 

    }); 

    async.parallel(userItem.venues, function(err, result) { 
     /* this code will run after all calls finished the job or 
     when any of the calls passes an error */ 
     if (err) 
      return console.log(err); 

     userItem.venues.push(result); 
    }); 
    ret.push(userItem); 
}); 

試過以下,以及,但不也行

users.forEach(function(user) { 

    var userItem = []; 
    async.series({ 

      setUserItem : function(callback) 
      { 
       userItem = user.getSanitised('ADM'); 
       callback(null, 'OK'); 
      }, 
      setUserVenues : function(callback) 
      { 
       userItem.venues = []; 
       user.adminVenueIds.forEach(function(adminVenueId,index) { 

        Venue.findOne({_id:adminVenueId}, function(error, venue) { 

         userItem.venues.push(venue.toObject()); 

         if((index+1) == user.adminVenueIds.length) 
          callback(null, 'OK'); 

        }); 
       }); 
      } 

     }, 
     function(error, results) { 

      if(error) 
       winston.error(error); 

      ret.push(userItem); 

     } 

    ); 


}); 

回答

0

我想你可能要考慮使用貓鼬。它是一個位於MongoDB之上的NodeJS應用程序層,提供了更像SQL的體驗。

http://mongoosejs.com

+0

是的,他們告訴我使用異步這是我在做什麼http://stackoverflow.com/a/17296329/1160952 – bicycle

+0

因此,異步基本上可以讓你實現承諾,一個很好的技術,但不是你真的想要完成IMO。你似乎試圖做一個SQL風格連接正確? sql語言中的 –

+0

是的,但不是現實中的。我只是爲每個venueID查找場地細節並將它們放在userItem字典中。不能相信這是如此困難。 – bicycle

1

你可以簡單地把一個if語句(在你的情況下把條件爲數組的長度),那麼當循環完成那麼你可以把它繼續通過調用一個函數來繼續做它的事(或把你的代碼在那裏,但它會開始顯得凌亂)

var ret = []; 
var test = []; 


for (var i = 0; i < 20; i++) { 
    for (var x = 0; x < 20; x++) { 
     setTimeout(function() { 
      test.push("Test"+x); 
      if (x === 20) { 
       finishIt(); 
      } 
     }, 300) 
    } 
} 


function finishIt() { 
    console.log(test); 
    ret.push(test); 
} 
+0

沒有幫助,會場查找調用保持異步,並與場館仍然爲空 – bicycle

+0

@bicycle你的代碼的一部分,你想保存最後? 'userItem.venues.push(result);'? – Datsik

+0

ret.push(userItem); – bicycle

0

我結束了以下解決方案。它很髒,但我想這只是nodejs是nodejs。

users.forEach(function(user) { 
    var userItem = user.getSanitised('ADM'); 
    userItem.venues = []; 


    user.adminVenueIds.forEach(function(adminVenueId) { 

     Venue.findOne({_id:adminVenueId}, function(error, venue) { 

      userItem.venues.push(venue.toObject()); 

     }); 
    }); 

    (function(){ 

     if(userItem.venues.length == user.adminVenueIds.length) { 

      ret.push(userItem); 

     } else { 
      setTimeout(arguments.callee, 30); 
     } 
    })(); 
});