mongoose将多个项目添加到数据库

这个代码有两个问题。 1)只有啤酒的最后一个元素被保存到数据库中。 2)保存到数据库的最后一个元素(n = beerObjects.length)有n个重复项。

function addBeersToDatabase(beerObjects) { for (i = 0; i < beerObjects.length; i++) { console.log(beerObjects[i].beerId); var currentBeer = beerObjects[i]; // check if beer is already in database Beer.findOne({'beerId': currentBeer.beerId}, function(err, beer){ if (err) { handleError(err); } if (beer) { // beer is already in database } else { // add new beer to database console.log(currentBeer.beerId); var newBeer = new Beer(); newBeer.beerId = currentBeer.beerId; newBeer.name = currentBeer.name; newBeer.description = currentBeer.description; newBeer.abv = currentBeer.abv; newBeer.image = currentBeer.image; newBeer.save(function(err) { if (err) { throw err; } }); } }); } 

}

我想遍历每一个啤酒,并将其信息保存到数据库。 我用findOne来防止重复,但这是行不通的。 第一个console.log()语句打印每个啤酒ID,但秒console.log()语句多次打印最后一个啤酒id。

问题在于,在findOnecallbackbeerId将始终设置为beerObjects的最后一个啤酒,因为循环在完成第一个callback之前完成 – 欢迎使用asynchronousJavaScript。

对此的一个补救办法是将您的findOne代码封装在IFFE(立即调用的函数expression式)中。 在从beerObject移动到下一个啤酒之前,此代码将完成。

这里是关于IFFE的更多信息

IFFE堆栈溢出

我对代码进行了快速传递,我相信这应该可行,但是您可能需要对内部代码进行一些调整。

 for(var i = 0; i < beerObjects.length; i++) { console.log(beerObjects[i].beerId); //var currentBeer = beerObjects[i]; dont need this now (function (currentBeer) { Beer.findOne({ beerId: currentBeer}, function(err, beer) { if(!err && !beer) { var newBeer = new Beer(); newBeer.beerId = currentBeer.beerId; newBeer.name = currentBeer.name; newBeer.description = currentBeer.description; newBeer.abv = currentBeer.abv; newBeer.image = currentBeer.image; newBeer.save(function(err) { // log your error here... }); } else if(!err) { console.log("Beer is in the system"); } else { console.log("ERROR: " + err); } } ); })(beerObjects[i].beerId); }