我会尝试尽可能简洁 - Mongoose似乎不会保存记录,直到整个脚本结束,即使异步调用save()部分:
var reallyBigData = require('./data.json');
var importData = function(data) {
var newObj = new Obj; // Mongoose Object
newObj.x = data.x;
newObj.save();
};
this.on('importData', importData);
for(var i in reallyBigData) {
this.emit('importData', reallyBigData[i]);
};
这是一个严格的简化,但你明白了。当我运行脚本并查询Mongo时,我没有看到任何记录,因为脚本正在运行。如果我将数字限制为30,并导入那些数字,它会快速完成,然后我会看到记录。
为什么Mongoose不会在脚本执行时保存每条记录?
答案 0 :(得分:2)
问题是x.save()
(或newObj.save()
)是异步的,除了Node本身之外,你没有任何等待它完成的事情。
异步,只有启动更新MongoDB中的集合并立即退出的任务。直到稍后,当调用可选的回调时,它实际上不会“完成”:
x.save(function (err, instance) {
// at this point, it either erred or saved
});
尽管如此,x.save()
几乎可以立即完成。及时查看的记录数量越少意味着您有竞争条件 - 这将首先完成:对MongoDB或Node / V8执行代码块的查询?
并且,使用EventEmitter
,至少如何在此处对其进行采样,不足以使您的循环异步,因为您仍然emit
同步事件emit()
将同步遍历任何处理程序。
但是,有许多“控制流”库可以提供帮助。其中包括promises,futures和async
等迭代器的实现:
var reallyBigData = require('./data.json');
async.each(Object.keys(reallyBigData),
function (key, callback) {
new Obj({ x: reallyBigData[key] }).save(callback);
},
function (err, results) {
// called with an `err` or an `Array` of `results` (saved `Obj`s)
}
);
答案 1 :(得分:0)
首先我认为你有一个讨厌的错误:
var importData = function(data) {
var newObj = new Obj; // Mongoose Object
Obj.x = data.x;
x.save();
};
最有可能读作:
var importData = function(data) {
var newObj = new Obj; // Mongoose Object
newObj.x = data.x;
newObj.save();
};
因为看起来您正在尝试对模式进行操作,而不是在您从模式中“新建”的模型上运行。那有意义吗?或许这就是你如何拥有它而你只是错过打字?我不知道你将如何从你现有的代码中获得预期的结果,无论它如何执行到数据库。也许正如你现在所拥有的那样,很难发现模型已经改变了值,或者它的验证失败了。