我有一个MongoDB数据库设置,其中一些对象具有唯一的代码(不是主键)。 我还应该注意到我使用的是NodeJS,这个代码在我的server.js中连接到MongoDB数据库。
要生成新代码,我随机生成一个代码,我想检查它是否已经存在。如果没有,那么我们使用它没问题,但如果它已经存在,我想生成另一个代码并再次检查它。这是我用来检查id是否已经存在的代码:
function createPartyId(callback) {
var min = 10000, max = 99999;
var partyId = -1, count = -1;
async.whilst(
function () { return count != 0; },
function (callback) {
partyId = min + Math.floor(Math.random() * (max - min + 1));
partyId = 88888;
getPartyIdCount(partyId, function(num) {
count = num;
});
},
function (err) {
}
);
}
function getPartyIdCount(partyId, callback) {
count = -1;
db.db_name.find({id: partyId}, function(err, records) {
if(err) {
console.log("There was an error executing the database query.");
callback(count);
}
count = records.length;
callback(count);
});
}
答案 0 :(得分:3)
首先,您是否有任何特殊原因未使用简单的数字增量序列?这种类型的代码容易产生效率低下,产生的数字越多,碰撞的可能性就越大,这意味着您将花费更多的时间为数据生成ID而不是处理其余的代码。不是个好主意。
但我仍然可以告诉你出了什么问题。
好的,所以getPartyIdCount()
只会,永远,永远,不会失败,返回undefined(或者,基本上没有)。
你的mongo调用处理回调中的返回值,并且该回调没有将其值赋给任何东西,因此return records.length
只会迷失为虚无。
您已将要与同步运行的createPartyId()
混合在一起,您的mongo调用必须异步运行。
return
始终使用包含function
的最近,因此在这种情况下,它与function(err, records)
一致,而不是function getPartyIdCount(partyId)
。
答案 1 :(得分:2)
(扩展我的评论)
问题是createPartyId是一个异步函数,但您试图同步返回该值。那不会奏效。一旦触摸异步操作,调用堆栈的其余部分也必须是异步的。
您没有包含调用此代码的代码,但我认为您希望它类似于:
var partyId = createPartyId();
// do stuff...
那不行。试试这个:
function createPartyId(callback) {
var min = 10000, max = 99999;
var partyId = -1, count = -1;
async.whilst(
function () { return (count == 0); },
function (callback) {
partyId = min + Math.floor(Math.random() * (max - min + 1));
partyId = 88888;
getPartyIdCount(partyId, function(err, num) {
if (!err) {
count = num;
}
callback(err);
});
},
function (err) {
// this is called when the loop ends, error or not
// Invoke outer callback to return the result
callback(err, count);
}
);
}
function getPartyIdCount(partyId, callback) {
count = -1;
db.db_name.find({id: partyId}, function(err, records) {
if(err) {
console.log("There was an error executing the database query.");
callback(err);
}
count = records.length;
callback(null, count);
});
}
(我还采用了默认的node.js约定,总是将错误作为回调函数的第一个参数返回。)
所以,要使用它,你会这样做:
getPartyId(function (err, num) {
if (err) { return aughItFellOver(err); }
// do stuff
});