在循环中保存到MongoDB

时间:2015-01-19 08:22:22

标签: javascript arrays node.js mongodb loops

我无法将新记录保存到mongoDB。我很确定我在我的代码中使用了一些我不完全理解的东西,我希望有人可以提供帮助。

我正在尝试为每只猫保存一条新记录到mongoDB。此代码适用于node.js

for(var x = 0; x < (cats.length - 1); x++){
    if (!blocked){
      console.log("x = "+x);
      var memberMessage = new Message();
      memberMessage.message = message.message;
      memberMessage.recipient = room[x].userId;

      memberMessage.save(function(err){
        if (err) console.log(err);

        console.log(memberMessage + " saved for "+cats[x].name);
      });
    }
  });
}

我记录&#34;猫的价值&#34;在循环之前,我确实得到了我期望的所有名称,所以我认为循环遍历数组会为每个循环存储一条新记录。

似乎发生的事情是,当我查看数据库时,似乎只保存了每个循环周期的最后一条记录。我不知道如何/为什么这样做。

对此有任何帮助表示赞赏,因为我是node.js和mongoDB的新手。

感谢。

2 个答案:

答案 0 :(得分:2)

您可以使用mongoose的批量创建功能:

var messages = [];
for(var x = 0; x < (cats.length - 1); x++) {
    if (!blocked) {
       var message = new Message();
       message.message = message.message;
       message.recipient = room[x].userId;
       messages.push(message);
    } 
}

Message.create(messages, function (err) {
  if (err) // ...
});

答案 1 :(得分:2)

那是因为save实际上是异步的I / O操作。现在,for循环实际上是同步的。 可以这样想:您的JS引擎按顺序执行它看到的每一行。假设这些行在堆栈上一个接一个地保留。当涉及save时,它将它放在一个不同的堆栈上(因为它是一个I / O操作,因此需要时间)并继续循环的其余部分。事实证明,引擎只有在完成旧堆栈的每一行之后才会检查这个新堆栈。因此,变量cats的值将是数组中的最后一项。因此,只保存最后一个值。

为了对抗这场悲剧,你可以使用多种方法:

  1. 闭包 - Read More
  2. 承诺 - Read More。有一个sweet library可以使mongo驱动程序更容易使用。
  3. 发电机等 - Read More。尚未准备好迎接黄金时段。

  4. 关于#2的注意事项 - 我不是该项目的贡献者,但与作者合作。我已经使用这个库超过一年了,而且速度快,真棒!

相关问题