最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Illegal break statement (Node.js) - Stack Overflow

programmeradmin2浏览0评论

Trying to find unique ID in Node.js and MongoDB, by creating a while loop that queries MongoDB for existing IDs, until a unique value is found. If the ID is already in use, a number is incremented on the end until Mongo returns nothing.

Everything is working, except for the break; statement when a unique ID is found. Node.js returns: SyntaxError: Illegal break statement

The code:

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);
    }

});

What am I doing wrong?

EDIT:

Here's the fixed up code using async if anyone needs it :)

        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);
            }
        });

Trying to find unique ID in Node.js and MongoDB, by creating a while loop that queries MongoDB for existing IDs, until a unique value is found. If the ID is already in use, a number is incremented on the end until Mongo returns nothing.

Everything is working, except for the break; statement when a unique ID is found. Node.js returns: SyntaxError: Illegal break statement

The code:

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);
    }

});

What am I doing wrong?

EDIT:

Here's the fixed up code using async if anyone needs it :)

        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);
            }
        });
Share Improve this question edited Sep 18, 2015 at 3:01 lmjohns3 7,5925 gold badges39 silver badges56 bronze badges asked Aug 2, 2013 at 18:29 alyxalyx 2,7336 gold badges44 silver badges69 bronze badges 6
  • Side note: once you get the syntax error fixed, you'll have a locked application. You can't use a synchronous while (1) with the asynchronous .findOne(). The latter requires the engine be idle to finish, which the former never lets it be. – Jonathan Lonowski Commented Aug 2, 2013 at 18:34
  • What's the best way to find a unique ID? – alyx Commented Aug 2, 2013 at 18:35
  • @jrbaldwinn: Pretty sure every object in a collection has a unique id assigned automagically when you add it. The object ID is kinda big and ugly, but the chances of it being duplicated, even in a cluster or whatever, are somewhere between slim and none. :) – cHao Commented Aug 2, 2013 at 18:40
  • Good point by @cHao. Rather than go through all of this trouble to create a unique ID, why not just use the '_id' property which MongoDB creates automatically for every document? – Owen Commented Aug 2, 2013 at 18:51
  • It's for unique URL generation based on a user's submission, I wish I could just use _id – alyx Commented Aug 2, 2013 at 19:07
 |  Show 1 more comment

1 Answer 1

Reset to default 18

Your break statement is not inside the body of a loop. It is, instead, inside the body of a function, namely the findOne callback. To see this more clearly, it can be helpful to temporarily use a named function as your callback handler:

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);
    }
});

It's pretty clear now that the break in the callback function body is not inside a loop! I've also made things break in other ways because the uniqueNumber and newUnique values are no longer in scope, but that's a different issue. :) The important thing to see here is that a function introduces a "hard" boundary in your code that can be difficult to see based purely on the syntax of the language. This is one of the reasons why this callback style of programming can be so tricky to get right.

In fact, it's much more difficult to do this than your original attempt at the code would imply. You'll need to have a way of passing a success signal up through possibly arbitrary layers of callbacks as you repeatedly call findOne and analyze the result (asynchronously).

You might get some help with this by using the excellent async library, for example https://github.com/caolan/async#whilst.

发布评论

评论列表(0)

  1. 暂无评论