【问题标题】:Q.allSettled executes before anything is pushed to the arrayQ.allSettled 在任何东西被推送到数组之前执行
【发布时间】:2014-09-06 20:05:41
【问题描述】:

我正在尝试学习如何将 Promise 与数组和一些异步 mongo 查询一起使用。这是我目前拥有的方法,但 Q.allSettled 在我的 mongo 查询 b/c 之前执行,尚未将任何内容推送到 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;
      }

【问题讨论】:

  • 你应该promisify mongo,然后编写promises - find 是异步的,所以allSettled 在一个空数组上运行并立即返回。
  • 这或多或少是我在我的问题中指出的。我不知道该怎么做,因此问题:p
  • 这 2 个链接是没有数组的示例。我知道如何做简单的事情。我被困在这个关于数组的特定问题上。请仔细阅读。
  • 你不能承诺每一个 - 你需要使用 .toArray 代替并承诺。

标签: javascript arrays promise


【解决方案1】:

两件事:

Q.allSettled 只会捕获在调用它时数组中的 Promise。 您需要等到填充完数组后,可能会承诺完成上面的each 调用。

另一个是Q.defer() 返回一个{promise, resolve} 对。您只需将 promise 添加到 promises 数组。

promises.push(def.promise);

【讨论】:

  • 正如 Benjamin 在 cmets 中所说,问题在于 each 调用没有“完成” - 它的回调将被异步调用多次。
  • 好的,所以我最终使用.each 实际工作,但它可能不像使用 .toArray 而不是每个解决方案那样优雅。在调用Q.allSettled 之前,我基本上必须创建另一个要调用的承诺。将 promise 推送到数组而不是对也是一个关键部分。
猜你喜欢
  • 1970-01-01
  • 2020-07-01
  • 1970-01-01
  • 2016-03-04
  • 1970-01-01
  • 1970-01-01
  • 2016-05-19
  • 2020-01-28
  • 1970-01-01
相关资源
最近更新 更多