0

できるだけ簡潔にしようと思います - save() 部分が非同期的に呼び出された場合でも、Mongoose はスクリプト全体が終了するまでレコードを保存しないようです:

var reallyBigData = require('./data.json');

var importData = function(data) {
  var newObj = new Obj; // Mongoose Object
  newObj.x = data.x;
  newObj.save();
};

this.on('importData', importData);

for(var i in reallyBigData) {
  this.emit('importData', reallyBigData[i]);
};

これは大まかな単純化ですが、アイデアはわかります。スクリプトを実行して Mongo にクエリを実行すると、スクリプトの実行中にレコードが表示されません。数を 30 に制限してインポートすると、すぐに終了し、後でレコードが表示されます。

スクリプトの実行中に Mongoose が各レコードを保存しないのはなぜですか?

4

2 に答える 2

2

問題は、x.save()(またはnewObj.save())が非同期であり、ノード自体以外に終了を待つものがないことです。

非同期であるため、MongoDBのコレクションを更新するタスクを開始するだけで、直後に終了します。オプションのコールバックが呼び出されるまで、実際には「実行」されません。

x.save(function (err, instance) {
    // at this point, it either erred or saved
});

x.save()ただし、ほぼ瞬時に終了することは可能です。表示されるまでに終了するレコードの数が少ないということは、競合状態が発生していることを意味します。これが最初に終了します。コードのブロックを実行するMongoDBまたはNode / V8へのクエリですか?

また、EventEmitter少なくともここでサンプリングした方法を使用するだけでは、ループを非同期にするのに十分ではありません。これは、emitイベントを同期的に実行emit()しており、ハンドラーを同期的にループするためです。

ただし、役立つ「制御フロー」ライブラリが多数あります。これらには、promise、futures、および次のようなイテレータの実装含まますasync

var reallyBigData = require('./data.json');

async.each(Object.keys(reallyBigData),
    function (key, callback) {
        new Obj({ x: reallyBigData[key] }).save(callback);
    },

    function (err, results) {
        // called with an `err` or an `Array` of `results` (saved `Obj`s)
    }
);
于 2013-03-08T21:13:33.970 に答える
0

まず、ここに厄介なエラーがあると思います:

var importData = function(data) {
  var newObj = new Obj; // Mongoose Object
  Obj.x = data.x;
  x.save();
};

おそらく次のように読む必要があります。

var importData = function(data) {
  var newObj = new Obj; // Mongoose Object
  newObj.x = data.x;
  newObj.save();
};

スキーマから「新しく」作成したモデルではなく、スキーマを操作しようとしているように見えるためです。それは理にかなっていますか?それとも、それがあなたのやり方で、タイプミスしただけですか?そのままでは、データベースに対してどのように実行されているかに関係なく、配置したコードから期待される結果がどのように得られるかわかりません。おそらく、現在のように、モデルの値が変更されたことを検出するのに苦労しているか、検証に失敗しています。

于 2013-03-08T21:58:21.493 に答える