2014-09-04 74 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

相关问题