Javascript 非法中断语句(Node.js)
尝试在Node.js和MongoDB中查找唯一ID,方法是创建一个while循环来查询MongoDB中的现有ID,直到找到唯一值。如果该ID已经在使用中,则会在末尾递增一个数字,直到Mongo不返回任何内容 一切正常,除了Javascript 非法中断语句(Node.js),javascript,node.js,mongodb,asynchronous,while-loop,Javascript,Node.js,Mongodb,Asynchronous,While Loop,尝试在Node.js和MongoDB中查找唯一ID,方法是创建一个while循环来查询MongoDB中的现有ID,直到找到唯一值。如果该ID已经在使用中,则会在末尾递增一个数字,直到Mongo不返回任何内容 一切正常,除了中断语句。Node.js返回:SyntaxError:非法中断语句 守则: db.collection('landmarks').findOne({'id':uniqueIDer}, function(err, data){ //if ID exists already
中断找到唯一ID时的代码>语句。Node.js返回:SyntaxError:非法中断语句
守则:
db.collection('landmarks').findOne({'id':uniqueIDer}, function(err, data){
//if ID exists already
if (data.id){
var uniqueNumber = 1;
while (1) {
var uniqueNum_string = uniqueNumber.toString();
var newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, function(err, data){
if (data.id){
uniqueNumber++;
}
else {
saveLandmark(newUnique);
break;
}
});
}
}
else {
saveLandmark(uniqueIDer);
}
});
我做错了什么
编辑:
下面是使用async(如果有人需要)修复的代码:)
break
语句不在循环体中。相反,它位于函数体内部,即findOne
回调。为了更清楚地了解这一点,暂时使用命名函数作为回调处理程序可能会有所帮助:
var cb = function(err, data){
if (data.id){
uniqueNumber++;
}
else {
saveLandmark(newUnique);
break; // not inside a loop!
}
};
db.collection('landmarks').findOne({'id':uniqueIDer}, function(err, data){
//if ID exists already
if (data.id){
var uniqueNumber = 1;
while (1) {
var uniqueNum_string = uniqueNumber.toString();
var newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, cb);
}
}
else {
saveLandmark(uniqueIDer);
}
});
现在很清楚,回调函数体中的break
不在循环中!我还以其他方式打破了局面,因为uniqueNumber
和newUnique
值不再在范围内,但这是另一个问题。:)这里要看到的重要一点是,函数在代码中引入了一个“硬”边界,纯粹基于语言的语法很难看到这个边界。这就是为什么这种回调风格的编程很难正确进行的原因之一
事实上,要做到这一点比您最初尝试编写代码所暗示的要困难得多。当您反复调用findOne
并分析结果(异步)时,您需要有一种通过可能的任意回调层向上传递成功信号的方法
例如,通过使用优秀的async
库,您可能会得到一些帮助。旁注:一旦修复了语法错误,您将拥有一个锁定的应用程序。您不能将同步while(1)
与异步.findOne()
一起使用。后者需要引擎闲置才能完成,而前者从未让引擎闲置。找到唯一ID的最佳方法是什么?@jrbaldwinn:非常确定集合中的每个对象在添加时都有一个自动分配的唯一ID。对象ID有点大,有点难看,但它被复制的可能性,即使是在集群或其他任何地方,也介于slim和none之间。:)赵的观点很好。与其经历所有这些麻烦来创建一个唯一的ID,为什么不直接使用MongoDB为每个文档自动创建的“\u ID”属性呢?这是基于用户提交的唯一URL生成,我希望我可以直接使用某种类型的idAsync代码,无论如何这是绝对必要的。所以……)
var cb = function(err, data){
if (data.id){
uniqueNumber++;
}
else {
saveLandmark(newUnique);
break; // not inside a loop!
}
};
db.collection('landmarks').findOne({'id':uniqueIDer}, function(err, data){
//if ID exists already
if (data.id){
var uniqueNumber = 1;
while (1) {
var uniqueNum_string = uniqueNumber.toString();
var newUnique = data.id + uniqueNum_string;
db.collection('landmarks').findOne({'id':newUnique}, cb);
}
}
else {
saveLandmark(uniqueIDer);
}
});