基于上一个问题Illegal break statement (Node.js)的建议,我实施了async.whilst()
,但它不是多次迭代。
我试图通过增加ID末尾的数字来查找唯一ID,并查询Mongo以查看该ID是否存在。如果它不存在,则找到唯一ID。它只循环一次,而不是找到唯一的。有什么问题?
代码:
var uniqueNumber = 1;
var newUnique;
async.whilst(
function () {
var uniqueNum_string = uniqueNumber.toString();
newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, function(err, data){
if (data){
console.log('entry found!');
return;
}
else {
console.log('entry not found!');
}
});
},
function (callback) {
uniqueNumber++;
},
function (err) {
saveLandmark(newUnique);
}
);
答案 0 :(得分:6)
我实际上找不到适合此任务的良好异步函数,所以我使用async.forever()一起攻击了一些东西。该函数将继续运行,直到您回调“错误”,这是您想要做的。
var uniqueNumber = 1;
var newUnique;
async.forever(function (next) {
var uniqueNum_string = uniqueNumber.toString();
newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, function(err, data){
if (data){
console.log('entry found!');
uniqueNumber++;
next();
}
else {
console.log('entry not found!');
next('unique!'); // This is where the looping is stopped
}
});
},
function () {
saveLandmark(newUnique);
});
关于您要解决的问题,在我看来,您希望插入具有唯一ID的新文档。如果情况确实如此,你会经常这样做,我会说这是一种非常低效的方法。如果您在数据库中有一千个文档,那么在您接近唯一ID之前,您将对数据库执行一千个完全无意义的请求。
更好的方法是将集合中的第一个文档按id降序排序(例如最高的id)。然后将该id增加1并尝试插入,直到它不被拒绝。因为即使您找到了唯一的ID,当您保存文档时,另一个插入可能是从另一个客户端或另一个实例(在负载平衡的情况下)。在您的情况下,这可能是也可能不是问题,我对您的应用程序知之甚少,我只是认为您应该了解当前方法和我的答案的缺点。
答案 1 :(得分:1)
这样的东西?我没有测试它,因为我不知道你正在使用什么数据库模块,但逻辑应该很明显。
function searchNubmersForResults(firstNumber, callback) {
//place other variables here, and you can collect the results within the closure, and send them as arguments to your callback
function testNumber(uniqueNumber) {
var uniqueNum_string = uniqueNumber.toString();
newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, function(err, data){
if (data){
console.log('entry found!');
callback(data);//We're done, use the callback on the data
} else {
console.log('entry not found!');
testNumber(uniqueNumber++);//Launch the next test
}
});
}
testNumber(firstNumber);//Laucn the first test
}
searchNubmersForResults(0, function(data) {
console.log('You have data now: ' + data);
});