MongoDB / Node.JS:在循环中插入文档-变量不更新

MongoDB / Node.JS: Inserting documents in a loop - variables not updating?

本文关键字:文档 插入 变量 更新 循环 Node JS MongoDB      更新时间:2023-09-26

我是相对(阅读:非常)新的MongoDB,我遇到了一些让我困惑的东西。

我有一个Employee对象数组,每个对象看起来基本是这样的:

{
  "Name" : "Jack Jackson",
  "Title" : "Senior Derp Engineer",
  "Specialties" : [
    "Kicking",
    "Screaming",
    "Throwing Tantrums"
  ]
}

…我想把它们每一个插入到我的收藏中作为一个文档。

这是代码(简化):

var collection = db.collection('Employees');
for (var ix=0; ix<allEntries.length; ix++) {
  var item = allEntries[ix];
  collection.insert(item, function(err, docs) {
    if (err) { MyErrorCallback(err); }
    else {
      // Insert specialties
      console.log(item["_id"] + ": " + item["Specialties"].length + " specialties.");
      // ...Code goes here which will insert a document into another collection associating the item's ObjectID with each specialty in the list.
    }
  });
}

我希望对于100个雇员的列表,我的控制台输出将包含allEntries中100个项目中每个项目的新创建的ObjectID,以及该项目中的专业数量的计数。相反,我得到的是插入的第一个项目的ObjectID,以及插入的第一个项目的Specialties的计数,重复100次。

为什么会这样?如何访问刚刚插入的项目(包括其新生成的ID),以便对其进行操作?这看起来像是某种范围问题,但对我来说没有意义。

许多谢谢。

更新:我在下面自我回答了检索对象的正确方法;但是我仍然很感兴趣,如果有人可以解释这里的变量作用域。这是令人困惑的。

这就是Node.js的工作方式,我花了很多时间来理解在像你这样的情况下发生了什么。Node.js希望是非阻塞的,这意味着这些代码是异步运行的。

例如:

for循环运行并将item设置为e.g.。"1"。现在它调用mongoDB函数。到现在为止一切都很好。问题是:Node.js不会继续等待for循环,直到你的回调函数被调用。for循环将继续。这意味着,该项目将获得值,例如。"2"了。当回调函数被调用时,for循环就结束了。每个函数都会记录:"2",因为这是变量的实际值。

你可以看到一个例子,如果你在回调函数中打印出i的值

插入回调函数中的docs变量包含了新插入的项目和它的objectID,所以只要对它做你想做的。

在回调中尝试console.log(docs)看看发生了什么

我知道如何获得对象:

var collection = db.collection('Employees');
for (var ix=0; ix<allEntries.length; ix++) {
  var item = allEntries[ix];
  collection.insert(item, function(err, docs) {
    if (err) { MyErrorCallback(err); }
    else {
      // Insert specialties
      var insertedItem = docs["ops"][0];
      console.log(insertedItem["_id"] + ": " + insertedItem["Specialties"].length + " specialties.");
      // ...Code goes here which will insert a document into another collection associating the item's ObjectID with each specialty in the list.
    }
  });
}

(关于"ops"项的信息在这里)。

然而,我绝对不明白这里的工作方式,因为传递到collection.insert()的函数可以访问item,但它的行为不以任何方式对我有意义…?