如何遍历对象并返回每个项目的mongoDB条目?

我在循环选区数据的对象方面遇到困难,在MongoDB中查找现有的条目并与它们做某些事情。 它总是成为一次又一次地在数据库中传递的同一条目。

我认为这是一个范围和时间问题。

我的代码:

for (key in jsonObj) { var newConstituent = new Constituent({ name : jsonObj[key]["Name"], email : jsonObj[key]["Email"], social : { twitter: { twitter_handle : jsonObj[key]["Twitter handle"], twitter_id : jsonObj[key]["User id"], timestamp : jsonObj[key]["Timestamp"] } } }); console.log(jsonObj[key]["Email"]); // this is fine here! Constituent.findOne({ email : jsonObj[key]["Email"] }, function(err, constitutents){ console.log(jsonObj[key]["Email"]); // here it's always the same record if (err) { console.log(err) } if (constitutents === 'null') { console.log("Constituent not found. Create new entry .. "); // console.log(newConstituent); newConstituent.save(function (err) { if (err) { console.log('db save error'); } }); } else { console.log("Constituent already exists .. "); } }); } 

我怀疑for循环比.findOne()执行更快,因此总是只获取传递给对象的最后一个项目。

有人能把我指向正确的方向吗?

几个这个。

  1. 不要for ... in ,特别是在节点中。 您可以使用Object.keys()以及此时的任何数组方法。 for ... in可以包含您不希望循环的值,除非您使用hasOwnProperty因为它将包含来自原型链的值。

  2. 电子邮件的原因是,你只是打印出你的查询了。 jsonObj包含在findOne的callbackjsonObj的范围内,因为你不是在findOnecallback中重新声明它。 所以,当调用callback函数的时候,不pipekey什么(我的猜测是它是你列表中的最后一个),就是你得到的电子邮件。 因为在JavaScript中,内部函数范围总是隐含地包含周围上下文的范围,所以您只需从封闭范围访问jsonObj

    为了澄清这一点,你的for ... in循环是同步的 – 也就是说解释器在处理任何新的指令之前完成所有的指令。 findOne ,如何是asynchronous的。 很简单,当你在这个循环中调用它时,它实际上并没有立即做任何事情 – 解释器仍在运行你的for ... in循环。 但是,在完成循环之后,要将更多的任务添加到执行堆栈中来运行。 所以循环完成,然后你的callback将开始执行。 由于for ... in循环完全结束,所以key设置为最终值。 所以,例如,如果它的最后一个值是foo ,这意味着EVERYTIME您的callback被调用,您将打印出jsonObj.foo因为for ... in循环已经完成。

    所以就像你问你的朋友说从A到J的信件,你离开房间去做10件事情。 做某事。 他完全完成了J,因为比你做的10件事中的1件要快得多。 现在每当你做完你的一件事情,你就回过头来说“你说的最新的信是什么”。 答案总是J,如果你需要知道每个任务的信件,你需要让他停止计数,或者以某种方式得到什么字母与任务的数量相对应的信息你正在表演。

    让他们等待不是一个好主意 – 这是浪费他们的时间。 但是,如果将findOne包装在传递key的值的新函数中,则可以使用。 请参阅下面的更新代码。

  3. 我不确定你的数据,但find一个将返回一个logging。 你把它变成一个复数( constitutents )的variables。 从阅读你的代码,我希望在这里回到一个单一的值。 (但是它仍然可以包装在一个数组中。)

既然你正在调用findOne并将查找操作的结果赋值给组件,你应该在console.log检查这个对象。

例如

 console.log(constitutents.email); // or console.log(constitutents[0].email) 

而不是

 console.log(jsonObj[key]["Email"]); 

(假设emailconstituants的财产)。

你可能只是尝试logging完整的constituants来validation你在找什么。

下面的代码将起作用的原因是,您正在将每个调用的key的当前值传递给该函数。 这意味着每次调用findConstituent时都会创build一个该variables的本地副本,而不是使用variables的闭包值。

 var newConstituent; function findConstituent(key){ Constituent.findOne({ email : jsonObj[key]["Email"] }, function(err, constitutents){ console.log(jsonObj[key]["Email"]); // here it's always the same record if (err) { console.log(err) } if (constitutents === 'null') { console.log("Constituent not found. Create new entry .. "); // console.log(newConstituent); newConstituent.save(function (err) { if (err) { console.log('db save error'); } }); } else { console.log("Constituent already exists .. "); } }); } for (key in jsonObj) { newConstituent = new Constituent({ name : jsonObj[key]["Name"], email : jsonObj[key]["Email"], social : { twitter: { twitter_handle : jsonObj[key]["Twitter handle"], twitter_id : jsonObj[key]["User id"], timestamp : jsonObj[key]["Timestamp"] } } }); findConstituent(key); }