2013-08-02 29 views
8

Cố gắng tìm ID duy nhất trong Node.js và MongoDB, bằng cách tạo vòng lặp while truy vấn MongoDB cho các ID hiện có, cho đến khi tìm thấy một giá trị duy nhất. Nếu ID đã được sử dụng, một số được tăng lên ở cuối cho đến khi Mongo không trả về gì cả.Tuyên bố ngắt không hợp lệ (Node.js)

Mọi thứ đang hoạt động, ngoại trừ câu hỏi break; khi tìm thấy ID duy nhất. lợi nhuận Node.js: SyntaxError: Illegal break statement

Mã:

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

}); 

Tôi đang làm gì sai?

EDIT:

Đây là cố định lên mã sử dụng async nếu có ai cần nó :)

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

Lưu ý phụ: khi bạn đã sửa lỗi cú pháp, bạn sẽ có một ứng dụng bị khóa. Bạn không thể sử dụng đồng bộ 'while (1)' với '.findOne()' không đồng bộ. Sau này yêu cầu động cơ được nhàn rỗi để kết thúc, mà trước đây không bao giờ cho phép nó được. –

+0

Cách tốt nhất để tìm ID duy nhất là gì? – alyx

+0

@jrbaldwinn: Khá chắc chắn rằng mọi đối tượng trong một bộ sưu tập đều có một id duy nhất được gán tự động khi bạn thêm nó. ID đối tượng là kinda lớn và xấu xí, nhưng cơ hội của nó được nhân đôi, ngay cả trong một cụm hoặc bất cứ điều gì, là một nơi nào đó giữa mỏng và không có. :) – cHao

Trả lời

15

tuyên bố break bạn không phải là bên trong cơ thể của một vòng lặp. Đó là, thay vào đó, bên trong cơ thể của một hàm, cụ thể là gọi lại findOne. Để thấy điều này rõ ràng hơn, nó có thể hữu ích để sử dụng tạm thời một hàm có tên như trình điều khiển callback của bạn:

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

Nó khá rõ ràng bây giờ mà các break trong cơ thể hàm callback không phải là bên trong một vòng lặp! Tôi cũng đã làm mọi thứ phá vỡ theo những cách khác vì các giá trị uniqueNumbernewUnique không còn nằm trong phạm vi, nhưng đó là một vấn đề khác. :) Điều quan trọng cần xem ở đây là hàm giới thiệu một ranh giới "cứng" trong mã của bạn có thể khó nhìn thấy hoàn toàn dựa trên cú pháp của ngôn ngữ. Đây là một trong những lý do tại sao kiểu gọi lại này của lập trình có thể rất khó để có được quyền.

Thực tế, việc thực hiện điều này khó hơn nhiều so với nỗ lực ban đầu của bạn tại mã sẽ ngụ ý. Bạn sẽ cần phải có một cách để truyền tín hiệu thành công qua các lớp gọi lại tùy ý có thể tùy ý khi bạn gọi số findOne và phân tích kết quả (không đồng bộ).

Bạn có thể nhận được trợ giúp với điều này bằng cách sử dụng thư viện xuất sắc async, ví dụ: https://github.com/caolan/async#whilst.

+1

+1 cho việc sử dụng async – Owen

+0

Mã không đồng bộ của một số loại sẽ là một điều cần thiết tuyệt đối. Vì thế. :) – cHao

Các vấn đề liên quan