break
của bạn câu lệnh không nằm trong phần thân của vòng lặp. Thay vào đó, nó nằm bên trong phần thân của một hàm, cụ thể là findOne
gọi lại. Để thấy điều này rõ ràng hơn, có thể hữu ích nếu tạm thời sử dụng một hàm được đặt tên làm trình xử lý lệnh gọi lại 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);
}
});
Bây giờ đã khá rõ ràng rằng break
trong phần thân hàm gọi lại không nằm trong vòng lặp! Tôi cũng đã khiến mọi thứ trở nên hỏng hóc theo những cách khác vì uniqueNumber
và newUnique
các giá trị không còn trong phạm vi, nhưng đó là một vấn đề khác. :) Điều quan trọng cần thấy ở đây là một hàm giới thiệu một ranh giới "cứng" trong mã của bạn mà có thể khó nhìn thấy chỉ dựa hoàn toàn vào cú pháp của ngôn ngữ. Đây là một trong những lý do tại sao kiểu lập trình gọi lại này có thể rất khó để làm đúng.
Trên thực tế, làm điều này khó hơn nhiều so với nỗ lực ban đầu của bạn với mã sẽ ngụ ý. Bạn sẽ cần có cách truyền tín hiệu thành công thông qua các lớp gọi lại có thể tùy ý khi bạn gọi liên tục findOne
và phân tích kết quả (không đồng bộ).
Bạn có thể nhận được một số trợ giúp về việc này bằng cách sử dụng async
tuyệt vời thư viện, ví dụ: https://github.com/caolan/async#whilst
.