非法 break 语句 (Node.js)

Posted

技术标签:

【中文标题】非法 break 语句 (Node.js)【英文标题】:Illegal break statement (Node.js) 【发布时间】:2013-08-04 03:08:42 【问题描述】:

尝试在 Node.js 和 MongoDB 中找到唯一 ID,方法是创建一个 while 循环,在 MongoDB 中查询现有 ID,直到找到唯一值。如果 ID 已被使用,则在末尾增加一个数字,直到 Mongo 什么也不返回。

一切正常,除了break; 找到唯一 ID 时的语句。 Node.js 返回:SyntaxError: Illegal break statement

代码:

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 的固定代码:)

        db.collection('landmarks').findOne('id':uniqueIDer, function(err, data)

            if (data)
                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,'world':worldVal, 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);
                );
            
            else 
                saveLandmark(uniqueIDer);
            
        );

【问题讨论】:

附注:一旦您修复了语法错误,您将拥有一个锁定的应用程序。您不能将同步 while (1) 与异步 .findOne() 一起使用。后者要求发动机空转才能完成,而前者绝不允许。 找到唯一 ID 的最佳方法是什么? @jrbaldwinn:很确定集合中的每个对象在添加时都会自动分配一个唯一的 ID。对象 ID 有点大而丑陋,但它被复制的机会,即使是在集群或其他任何地方,都介于微乎其微和没有之间。 :) @cHao 说的好。为什么不使用 MongoDB 为每个文档自动创建的“_id”属性,而不是通过所有这些麻烦来创建唯一 ID? 它是根据用户提交的唯一URL生成,我希望我可以只使用_id 【参考方案1】:

您的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 不在循环中!我还以其他方式破坏了事情,因为 uniqueNumbernewUnique 值不再在范围内,但这是一个不同的问题。 :) 这里要看到的重要一点是,函数在代码中引入了“硬”边界,纯粹基于语言的语法很难看到。这就是为什么这种回调风格的编程很难做到正确的原因之一。

事实上,做到这一点比您最初尝试编写代码所暗示的要困难得多。当您反复调用findOne 并分析结果(异步)时,您需要有一种方法通过可能的任意回调层向上传递成功信号。

您可以通过使用出色的 async 库获得一些帮助,例如 https://github.com/caolan/async#whilst。

【讨论】:

某种类型的异步代码无论如何都是绝对必要的。所以。 :)

以上是关于非法 break 语句 (Node.js)的主要内容,如果未能解决你的问题,请参考以下文章

iPhone 14/Pro卫星紧急求救上线;非法采集用户位置,谷歌赔偿3.9亿美元;Node.js 19.1.0发布|极客头条

Node.js知识点整理之----REPL

树莓派安装node.js

sql更新语句node.js

Node.js catch 语句返回不会停止执行

node.js 如何决定一个语句是不是被异步处理?