javascript - 非法 break 语句 (Node.js)

标签 javascript node.js mongodb asynchronous while-loop

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

一切正常,除了找到唯一 ID 时的 break; 语句。 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);
            }
        });

最佳答案

您的 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 .

关于javascript - 非法 break 语句 (Node.js),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18023787/

相关文章:

node.js - 如何使用 CAS 身份验证制作 Angular 5 + Node 应用程序?

node.js - 当数字与动态字段名称关联时 $inc 的 Mongo Node 语法

python - 如何使用 MongoEngine 运行这个 MongoDB 查询

javascript - 如何使用 PHP GET 请求打开 Bootstrap 模式?

node.js - Socket.io 连接事件未在服务器上触发

Javascript 回调函数 - Node.js

mongodb - 使用 PyMongo 执行正则表达式查询

javascript - D3 制作新的、更小的 CSV 文件

JavaScript 检查是否为 Chrome、Firefox 和 Opera 安装了浏览器扩展

javascript - AngularJS 和使用哈希 URL 的 js/css 库