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。
问题在于,在findOne
callbackbeerId
将始终设置为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); }