あなたの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
のため、他の方法でも問題が発生しました。 およびnewUnique
値はスコープ内になくなりましたが、それは別の問題です。 :)ここで重要なことは、関数がコードに「ハード」境界を導入することです。これは、純粋に言語の構文に基づいて見るのは難しい場合があります。これが、このコールバックスタイルのプログラミングが非常に難しい理由の1つです。
実際、これを行うことは、コードでの最初の試みが意味するよりもはるかに困難です。 findOne
を繰り返し呼び出すときに、コールバックの任意のレイヤーを介して成功シグナルを渡す方法が必要になります。 結果を(非同期で)分析します。
優れたasync
を使用すると、これについていくらかの助けが得られるかもしれません。 ライブラリ、たとえば https://github.com/caolan/async#whilst
。