Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 非法中断语句(Node.js)_Javascript_Node.js_Mongodb_Asynchronous_While Loop - Fatal编程技术网

Javascript 非法中断语句(Node.js)

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

尝试在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
    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);
    }
});