【问题标题】:Add mongoose query (promise) to array and do parallel operations将猫鼬查询(承诺)添加到数组并进行并行操作
【发布时间】:2017-03-30 22:13:31
【问题描述】:

我正在使用 mongoose 在 MongoDB 中进行一些操作。我想搜索用户创建的所有任务,然后将值 isPerforming 设置为 false 并保存。 文档说猫鼬查询(带有.exec() 函数)是承诺的。有很多任务,所以我认为将它们推送到数组并使用Q.all([...]) 进行并行保存操作。问题是当我尝试做.push() 时。我的代码在第一次 .push() 操作后停止。 还有其他方法吗?

 function stopUserTasks(userid) {

    var deferred = Q.defer();
    var query = Task.find({'_creator': userid}).exec();

    query.then(function(data, err) {
        console.log('found: ');
        console.log(data);
        if (err) {
          deferred.reject(err);
        }
        return data;
      })
      .then(function(data, err) {

        var len = data.length;
        var saveTasksPromises = [];

        for(var i = len; i--; ) {
          console.log(data[i]._id);
          saveTasksPromises.push(Task.save({'_id': data[i]._id, 'isPerforming': false}).exec() );
        }
        return saveTasksPromises;

      })
      .then(function(data, err) {
        console.log(data);

        deferred.resolve();
      });

      return deferred.promise;

  }// #stopUserTasks

【问题讨论】:

  • 请不要使用explicit promise creation antipattern。如果您必须将一种类型的 Promise (mongoose) 转换为另一种 (q),请使用 Promise.resolve(otherPromise)Q(otherPromise)

标签: javascript node.js mongoose promise


【解决方案1】:

Model.save()实际上返回promise,所以不需要写Model.save().exec(),所以你的行需要调整如下:

saveTasksPromises.push(Task.save({'_id': element._id, 'isPerforming': false}))

同样使用Q.all,整个函数如下:

function stopUserTasks(userid) {
  var deferred = Q.defer();
  var promise = Task.find({'_creator': userid}).exec();

  promise
    .then(function(data) {
      var len = data.length;
      var saveTasksPromises = [];

      for(var i = len; i--; ) {
        saveTasksPromises.push(Task.save({'_id': data[i]._id, 'isPerforming': false}));
      }
      return Q.all(saveTasksPromises);
    })
    .then(function(data) {
      deferred.resolve(data);
    });
    .catch(function(err) {
      deferred.reject(err);
    });
    return deferred.promise;
}

【讨论】:

  • 它不工作。 deferred 承诺未解决或拒绝。在控制台中只出现第一个 data._id。当然element._id应该换成data[i]._id
  • 在将Q.all 付诸实施后,检查上面编辑过的答案。
  • 它几乎可以工作.. 感谢您的建议,我自己弄清楚了如何去做。它在循环中工作时我们将saveTasksPromises.push(Task.save({'_id': data[i]._id, 'isPerforming': false})); 更改为var task = data[i]; task.isPerforming = false; saveTasksPromises.push(task.save());
  • 请不要使用explicit promise creation antipattern。如果您必须将一种类型的 Promise (mongoose) 转换为另一种 (q),请使用 Promise.resolve(otherPromise)Q(otherPromise)
  • @Tamas Hegedus:感谢您指出。我是菜鸟,但这不是以不好的方式编码的借口:)
猜你喜欢
  • 2015-03-05
  • 2019-05-27
  • 2015-04-01
  • 1970-01-01
  • 2019-05-31
  • 2015-05-12
  • 1970-01-01
  • 2015-11-19
  • 2012-12-14
相关资源
最近更新 更多