我正在使用Node.js和MongoDB(Mongoose.js)进行API。我制作了一个“安装”脚本,用一些示例数据填充数据库,比如用户和其他东西。
问题是当我尝试添加递归插入时。
我将999个文档添加到一个集合(父亲),并为另一个集合(儿子)中的每个父文档添加12个文档。
父亲集合有999个文件。 但是当我期待Sons系列中的11988个文件时,儿子收藏只有1188个。
模型是正确的。我有很多单元测试来验证这些操作。
这是我的代码:
var mongoose = require('mongoose');
var conf = require('../config/dbConfig');
var fatherDb = require('../model/father');
var sonsDb = require('../model/son');
var db_lnk = conf.mongoSrv();
global.db = (global.db ? global.db : mongoose.createConnection(db_lnk));
function addFather(idSome, idOther){
console.log("Adding Fathers");
fatherDb.count({active:true}, function(err,count){
if(!err){
var max = (999-count);
for(i=0; i<max; i++){
var father = new fatherDb({
"name":"Father " + (i+1),
"createdBy" : "55ad5f224f350c123b8e2bda",
"modifyBy" : "55ad5f224f350c123b8e2bda",
"active" : true,
"_some" : idSome,
"_other" : idOther,
"__v" : 0
});
father.save(function(err, data){
console.log("Adding 12 Sons to Father # " + i);
var idFather = data._id;
for (var x = 1; x < 13; x++) {
var son = new sonsDb({
"name": "Son " + x,
"position": x,
"createdBy": "55ad5f442f350c431b8e2bda",
"modifyBy": "55ad5f442f350c431b8e2bda",
"active": true,
"_father": idFather,
"__v": 0
});
son.save(function (err) {
console.log("Adding Son " + x);
if(i == max) {
endInstall();
}
});
}
});
}
}else{
console.log("Error");
endInstall();
}
});
}
function endInstall(){
console.log("Ending Installation");
process.exit();
}
addFather('SOMEid','OtherId');
答案 0 :(得分:1)
.save()
是一个异步函数,因此for
循环将在它们完成之前继续运行它们。这样i
将比您预期的更早达到max
。
换句话说,i
在所有max
被解雇后未到达father.save
,而son.save
将过早执行endInstall()
。
async是一个处理这种情况的库。如果您想继续使用计数器,请查看times method。
类似的东西:
// generate max fathers
async.times(max, function(n, next_father){
var father = ...
father.save(function(err){
// generate 12 sons
async.times(12, function(m, next_son){
var son = ...
son.save(function(err){
next_son(err);
});
}, function(err, sons){
next_father(err);
});
});
}, function(err, fathers) {
// it's done
});
这样你可以确保一切都已完成。
答案 1 :(得分:0)
这一步在完成所有处理之前调用你的endInstall方法。
son.save(function (err) {
console.log("Adding Son " + x);
if(i == max) {
endInstall();
}
});
}
使用异步库,而不是尝试使用for循环。