0

私は名前の配列を持っています:

var names = ["ケリー", "エイミー", "マーク"]

Person が nodejs の単なる Mongoose モデルであると仮定すると、次のようにして、各名前をドキュメントとして mongodb に保存したいと思います。

for(var i = 0; i < names.length; i++) {
           name_now = names[i];
        Person.findOne({ name: name_now},
            function(err, doc) {
                if(!err && !doc) {
                    var personDoc = new PersonDoc();
                    personDoc.name = name_now;
                    console.log(personDoc.name);
                    personDoc.save(function(err) {});
                } else if(!err) {
                    console.log("Person is in the system");
                } else {
                    console.log("ERROR: " + err);
                }
            }
        )   
}

「スケジュールの作成中にエラーが発生しました: MongoError: E11000 duplicate key error index:..... dup key: {: "Mark"}」というメッセージが引き続き表示されるため、問題が発生しています。また、リスト内の各名前ではなく、「マーク」(リスト内の最後の要素) を 3 回挿入しようとしているようです。

ループ内で現在の人物の名前を出力しようとすると (console.log(personDoc.name); を使用)、「マーク」が 3 回表示されます...「マーク」のみが保存されているようですデータベースと他の誰も...これに対処する適切な方法は何ですか?

4

1 に答える 1

1

最初のコールバックが呼び出される前にループが完了するため、findOneコールバック中name_nowは常に姓に設定されます。各反復中に現在の値をキャプチャし、コールバックで使用するために保存する即時関数を作成する必要があります。namesforname_now

for(var i = 0; i < names.length; i++) {
    (function (name_now) {
        Person.findOne({ name: name_now},
            function(err, doc) {
                if(!err && !doc) {
                    var personDoc = new PersonDoc();
                    personDoc.name = name_now;
                    console.log(personDoc.name);
                    personDoc.save(function(err) {});
                } else if(!err) {
                    console.log("Person is in the system");
                } else {
                    console.log("ERROR: " + err);
                }
            }
        );   
    )(names[i]);
}
于 2012-09-25T20:31:57.820 に答える