为什么Mongoose不会在脚本执行时保存记录?

时间:2013-03-08 20:21:01

标签: node.js mongodb mongoose

我会尝试尽可能简洁 - 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不会在脚本执行时保存每条记录?

2 个答案:

答案 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()将同步遍历任何处理程序。

但是,有许多“控制流”库可以提供帮助。其中包括promisesfuturesasync等迭代器的实现:

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();
};

因为看起来您正在尝试对模式进行操作,而不是在您从模式中“新建”的模型上运行。那有意义吗?或许这就是你如何拥有它而你只是错过打字?我不知道你将如何从你现有的代码中获得预期的结果,无论它如何执行到数据库。也许正如你现在所拥有的那样,很难发现模型已经改变了值,或者它的验证失败了。