Mongoose没有在循环中保存所有文档

时间:2015-07-02 18:10:35

标签: node.js mongodb express

所以我在POST api的Express应用程序中有以下代码:

var dashSchema = new mongoose.Schema({
  key: 'string',
  status: 'string',
  assignee: 'string',
  summary: 'string'
});

var dashData = mongoose.model('dashData', dashSchema);


app.post('/api/data', function(req, res) {
  var issues = req.body.issues;

  for (var i=0;i<issues.length;i++) {
    dashData.create({key: issues[i].key, status: issues[i].fields.status.name, assignee: issues[i].fields.assignee, summary: issues[i].fields.summary});
  }

  res.end();
  });

每当我发布5&#34;问题&#34;只有前两个被写入MongoDB。我认为这是因为它可以在迭代循环所需的时间内编写,但我不知道如何使其写入所有数据,然后返回响应。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

在Mongoose中,.create返回一个承诺。安装一个类似bluebird的承诺库,可以访问Promise.all,您可以执行此操作:

var Promise = require('bluebird'); // could also be Q or another A+ library

app.post('/api/data', function(req, res, next) {
  var issues = req.body.issues;

  // map the issues to an array of promises for created dashData docs
  var createdPromises = issues.map(function(issue){
    return dashData.create({key: issue.key, status: issue.fields.status.name, assignee: issue.fields.assignee, summary: issue.fields.summary}); // returns a promise
  });

  Promise.all(createdPromises).then(function(results){
    res.json(results); // only sends when all docs have been created
  }).then(null, next); // error handler - pass to `next`

});

答案 1 :(得分:1)

最简单的方法是在达到最后一次迭代时结束响应:

  for (var i=0;i<issues.length;i++) {
    dashData.create({key: issues[i].key, status: issues[i].fields.status.name, assignee: issues[i].fields.assignee, summary: issues[i].fields.summary});
    if(i === issues.length - 1) return res.end();
  }

或者,您可以使用async模块获得更多功能,尤其是在您需要等待所有查询完成时。

<强>更新

正如Gabriel正确指出的那样,上面的代码并不能确保查询在发送响应之前完成执行。我想我已经提到你应该使用async especially if you need to wait for all the queries to complete。无论如何,如果你希望没有async或Promises的开销,你可以做类似的事情:

  var ctr = 0;
  issues.forEach(function(issue){
        dashData.create({key: issue.key, status: issue.fields.status.name, assignee: issue.fields.assignee, summary: issue.fields.summary}, function(err, doc){
            if (err) { return errorHandler(err); }
            ctr++;
            if (ctr === issues.length) return res.end();
        });
  });