我对此代码有两个问题。 1)只将beerObjects的最后一个元素保存到数据库中。 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。
答案 0 :(得分:3)
问题在于findOne
回调 - 您的beerId
将始终设置为beerObjects
中的最后一个啤酒,因为循环在您第一次回调之前结束 - 欢迎使用异步javascript。
对此的一个补救措施是将findOne
代码包装在IFFE(立即调用的函数表达式)中。此代码将在继续使用beerObject的下一个啤酒之前完成。
以下是关于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);
}