Заявление о нелегальном нарушении (Node.js)

Попытка найти уникальный идентификатор в Node.js и MongoDB, создав цикл while, который запрашивает MongoDB для существующих идентификаторов, пока не будет найдено уникальное значение. Если идентификатор уже используется, число увеличивается в конце, пока Mongo ничего не возвращает.

Все работает, кроме 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 в функции функции обратного вызова не находится внутри цикла! Я также делал вещи uniqueNumber другими способами, потому что uniqueNumber значения uniqueNumber и newUnique больше не занимают места, но это другая проблема. 🙂 Важно отметить, что функция вводит «жесткую» границу в вашем коде, которую трудно понять, основываясь исключительно на синтаксисе языка. Это одна из причин, по которой этот стиль обратного вызова программирования может быть настолько сложным, чтобы получить право.

    На самом деле гораздо сложнее сделать это, чем предполагала ваша первоначальная попытка кода. Вам нужно будет передать сигнал успеха через, возможно, произвольные уровни обратных вызовов, поскольку вы повторно вызываете findOne и анализируете результат (асинхронно).

    Вы можете получить некоторую помощь в этом, используя отличную async библиотеку, например https://github.com/caolan/async#whilst .