所以我在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。我认为这是因为它可以在迭代循环所需的时间内编写,但我不知道如何使其写入所有数据,然后返回响应。
有什么想法吗?
答案 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();
});
});