2014-09-04 29 views
0

我正試圖學習如何使用數組和一些異步mongo查詢的promise。這是我目前使用的方法,但Q.allSettled在我的mongo查詢b/c之前執行,沒有任何數據已被推送到Q.allSettled正在查看的陣列。Q.allSettled在將任何內容推送到數組之前執行

如何修改此方法以便在執行Q.allSettled.spread之前執行所有異步查詢?

function buildCaseObject() { 

     var returnPromise = Q.defer(); 
     var promises = []; 
     var allObjects = []; 

     var subjects = rdb.collection('subjects'); 
     var observations = rdb.collection('observation'); 

     // Loop through all subjects from current subject list 
     subjects.find({'player._id': {$elemMatch: {root: '1.2.3.99.100.2', extension: {$in : subjectList}}}}).each(function(err, subject) { 

      var def = Q.defer(); 
      promises.push(def); 

      if (err) { 
      def.reject(err); 
      } else if (subject== null) { 
      return def.resolve(); 
      } 

      var caseObject = {}; 
      caseObject.subject= clone(subject); 

      // Add observations to the subject 
      observations.find({subjectId: subject._id}).toArray(function(err, allObs) { 

      if (err) { 
       def.reject(err); 
      } 

      caseObject.observations = clone(allObs); 
      allObjects.push(caseObject); 
      def.resolve(); 
      }); 

     }); 

     Q.allSettled(promises).then(function() { 
      // GETTING IN HERE BEFORE GETTING INTO THE CALLBACK OF subjects.find. 
      // THEREFORE THE ARRAY IS EMPTY 
      console.log('in spread'); 
      console.log(allObjects.length); 
      returnPromise.resolve(allObjects); 
     }).fail(function(err) { 
      returnPromise.reject(err); 
     }); 

     return returnPromise.promise; 
     } 
+0

您應該promisify mongo,然後撰寫諾言 - 查找是異步的,所以allSettled運行在一個空數組並立即返回。 – 2014-09-04 20:34:42

+0

這或多或少是我在我的問題中指出的。我不知道該怎麼做,因此問題:p – Catfish 2014-09-04 20:39:15

+0

http://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises並且還閱讀http://stackoverflow.com/questions/23803743/what-is-the-deferred-antipattern-and-how-do-i-avoid-it – 2014-09-04 20:41:38

回答

1

兩件事情:

Q.allSettled將只捕獲是在它被調用的時候數組中的承諾。 您需要等待,直到您已經填充了陣列,可能需要承諾完成上面的each調用。

另一種是Q.defer()返回{promise, resolve}對。您只需將promise添加到promises數組中。

promises.push(def.promise); 
+1

正如Benjamin在評論中所述,問題是沒有「每個」調用的「完成」 - 它的回調將被異步調用多次。 – Bergi 2014-09-06 12:10:58

+0

好的,我最終使用'.each'實現了這個工作,但它可能不像使用.toArray而不是每個解決方案那麼優雅。在調用'Q.allSettled'之前,我基本上必須創建另一個承諾。同時推動對陣列的承諾,而不是雙方的承諾也是關鍵。 – Catfish 2014-09-09 20:34:18

相關問題