2014-11-08 11 views
0

我正在使用Async實用程序模塊從Mongodb數據庫返回項目。我想要異步執行。嘗試返回這些項目時遇到問題。在返回所有數據之前儘早完成循環中的異步mongodb查找

一旦所有的User.find()'s已完成,我想發起回調,現在async.each()提前終止,並且只有當它應該全部返回時給我一個來自數據庫的項目。

的代碼如下:

async.each(lessons, function(lesson, next) { // For each item in lesson array 
    if (_.isEmpty(lesson.lesson_grades) == true) { // Check if the grades array is empty 
     return; 
    } else { 
     async.each(lesson.lesson_grades, function(grade, next) { // For each grade in grade array 
      User.find({ // Find user from grade user_id 
       _id: grade.user_id, 
      }, '-salt -hashedPassword', function(err, user) { 

       grade["name"] = user[0].name; // Add name 
       grade["email"] = user[0].email; // Add email 

       next(); // !! I think this is where the problem lies, it fires next() once the first item has been returned - so it doesn't get to the other items !! 
      }); 
     }, function(err) { 
      next(lessons); 
     }); 
    } 
}, function(lessons, err) { 
    return res.json(200, lessons); // Return modified lessons (with name and email) to browser, currently only returns one but returns them all if a setTimeout() is added, making it a premature callback problem 
}); 

有人能指出我如何正確地做這個正確的方向?我應該跟蹤迭代嗎?任何幫助,將不勝感激。

回答

0

約定跟着異步是一個回調函數有兩個參數:錯誤和結果,按順序。錯誤和結果之間的區別很重要,因爲如果異步收到錯誤,異步立即完成。說function(err) { next(lessons); }的部分是錯誤的 - 異步將lessons誤解爲錯誤,因爲它是真的。它應該是:

function(err, result) { 
    next(err, result); 
} 

或者事實上,您可以用next替換該功能。

另外,在末尾function(lessons, error)應該是function(error)

另一件需要注意的事情是:您必須確保每個回調只被調用一次。但是如果它運行的是if塊而不是else塊,則next永遠不會被調用;異步將永遠不會完成。它不會阻止其他代碼運行,但它永遠不會達到return res.json(200, lessons);。 (它也可能會泄漏內存,我不確定。)

最後一件事:返回回調內的結果將不會執行任何操作。它看起來像你試圖從一個同步函數調用所有這些異步代碼;這不起作用。 res.json將被調用,但是如果它返回一個值,那麼你可能想使用該值作爲另一個回調函數的參數。但是我需要更多關於你想要做什麼的信息。

+0

感謝您花時間回答。我已經做出了您建議的更改,但我仍然遇到同樣的問題。你能指導我如何改寫它嗎?自你發佈這個答案以來,我一整天都在嘗試。謝謝。 – 2014-11-09 06:21:44

+0

你是如何得到這個輸出的?另外,請注意我對我的回答的改變 - 最後的函數不應該有'lessons'作爲參數(它應該是一個閉包變量)。 – 2014-11-09 16:05:43

相關問題