2012-08-11 5 views
7

Mongooseでバッチ保存を管理するにはどうすればよいですか?私はそれがまだできないことがありました:マングースでpromisesマングースJSは約束しますか?またはバッチ保存を管理する方法

qのようないくつかのフロー制御ライブラリの使用方法について、いくつかの言及をtheresのが、私にも気づく、それを使用することができますか? jQueryので繰延ように私にできること/並列に複数のマングースのドキュメントを保存するには

$.when(obj1.save(), obj2.save(), obj3.save()).then -> 
    # do something? 

答えて

3

asyncモジュールのparallel機能を試してください。

var functions = []; 

for (var i=0; i < docs.length; i++) { 
    functions.push((function(doc) { 
     return function(callback) { 
      doc.save(callback); 
     }; 
    })(docs[i])); 
} 

async.parallel(functions, function(err, results) { 
    console.log(err); 
    console.log(results); 
}); 
2

を約束、あなたはこのような単純な何かを行うことができます(あなたが保存する文書のdocsという名前の配列を持っていると仮定します):

var count = docs.length; 
docs.forEach(function(doc) { 
    doc.save(function(err, result) { 
     if (--count === 0) { 
      // All done; call containing function's callback 
      return callback(); 
     } 
    }); 
}); 
1

async parallelを使用する方法の洗練された例は次のようになります。

async.parallel([obj1.save, obj2.save, obj3.save], callback); 

大会は非同期のようにマングースでも同じであるので(ERR、コールバック)あなたはそれらをラップする必要はありません。あなた自身のコールバックは、あなたのセーブコールを配列に追加するだけで、すべてが終了したらコールバックを得るでしょう。

+1

または配列をバッチ保存する: async.map(オブジェクト、関数(オブジェクト、次){オブジェクト・セーブ(次)}、コールバック); –

+0

ありがとうございます。私はマップのアプローチが良いと思う。しかし、どちらも問題ありません。 –

9

はい、これは約束で行うことができます。あなたはQ約束ライブラリを使用していた場合、あなたは可能性があり、再書き込みする@ matz3のようなコード:私たちは、ループ内の時間ですべての操作1を開始

var tasks = []; 

for (var i=0; i < docs.length; i++) { 
    tasks.push(docs[i].save()); 
} 

Q.all(tasks) 
    .then(function(results) { 
    console.log(results); 
    }, function (err) { 
    console.log(err); 
    }); 

が、我々はそれらのいずれかのを待つことはありません完了したので、それらは並行して実行されます。配列に結果のプレースホルダーのように働く約束事を追加します。私たちは、一連の約束がすべて完了するのを待っています。

ほとんど良いPromises/A+互換ライブラリがasync.queue程度Q.all

+0

これは新しく間違っている可能性があります。しかし、配列を作成する際にsave()を使用すると、()を除外して配列を構築する際に評価されないはずです。 – Slappy

+1

いいえ、私は配列の操作を開始していますので、 '()'をインクルードする必要があります。それは配列に入れた '約束'オブジェクトを返します。実際の最終結果ではなく、約束しか得られないので、それは平行です。最後に、私はそれらの約束が解決するのを待つ。 – ForbesLindesay

+1

'()'を省略すると、一連の関数が得られますが、関数の配列では一般的に認識されることはありません。たとえば、並列ではなく一度に1つずつ実行したいと思うかもしれませんし、約束を返すのではなくコールバックを取るかもしれません。しかし、一連の約束が達成されるのを待つ認識された方法があります。 – ForbesLindesay

-1

何にいくつかの同等のものを持っています。
簡単な例:

var queue = async.queue(function(obj, callback) { 
    return obj.save(callback); 
}); 

for (var i in objs) { 
    var obj = objs[i]; 
    // Some changes on object obj 
    queue.push(obj); 
} 

あなたはキューが空にされた後にコールバックが必要な場合:

var emptyQueue = true; 
var queue = async.queue(function(obj, callback) { 
    return obj.save(callback); 
}); 
queue.drain = function() { 
    // Every callbacks are finished 
    // bigCallback(); 
}; 

for (var i in objs) { 
    var obj = objs[i]; 
    // Some changes on object obj 
    queue.push(obj); 
    emptyQueue = false; 
} 
if (emptyQueue) { 
    // Call manually queue drain in case of the queue is empty 
    // and we need to call bigCallback() for example 
    return queue.drain(); 
} 
+0

なぜdownvote? – mathieug

-1

@ForbesLindesayをなぜあなたは約束のマングースの実装を使用して、独自に作成することができたときに外部ライブラリをロードしますすべて ?

すべてでmongoose約束を強化するモジュールを作成します。

var Promise = require("mongoose").Promise; 

Promise.all = function(promises) { 
    var mainPromise = new Promise(); 
    if (promises.lenght == 0) { 
    mainPromise.resolve(null, promises); 
    } 

    var pending = 0; 
    promises.forEach(function(p, i) { 
    pending++; 
    p.then(function(val) { 
     promises[i] = val; 
     if (--pending === 0) { 
     mainPromise.resolve(null, promises); 
     } 
    }, function(err) { 
     mainPromise.reject(err); 
    }); 
    }); 

    return mainPromise; 
} 

module.exports = Promise; 

そして、マングースとそれを使用します。

require('./promise') 

... 

var tasks = []; 

for (var i=0; i < docs.length; i++) { 
    tasks.push(docs[i].save()); 
} 

mongoose.Promise.all(tasks) 
    .then(function(results) { 
    console.log(results); 
    }, function (err) { 
    console.log(err); 
    }); 
+0

さて、mongooseの内部で使用されているmpromiseを使う方が簡単です: 'var Promise = require( 'mpromise');'次に 'Promise.all(...)'を使います。 –

4

マングースは今、あなたが実施を約束かを選択することができます。

ここではノードを使用しています。JSデフォルトのシステムの約束(ES6)は

var mongoose = require('mongoose'); 
    mongoose.Promise = global.Promise; // use system implementation 

Promise.all(obj1.save(), obj2.save(), obj3.save()) 
.then(function(resultSaves) { 

    console.log('parallel promise save result :'); 
    console.log(resultSaves); 
    mongoose.disconnect(); 

}).catch(function(err) { 

    console.log('ERROR on promise save :'); 
    console.log(err); 
    mongoose.disconnect(); 
}); 

ノード--version V4.1.1

[email protected] mongoose以来

1

は、今あなたがPromise.all().then()を使用することが約束をサポートしていますので、それnodejsに焼きすべての約束が解決されたときに戻ります。あなたはいつもsave()メソッドを呼び出している場合

Promise.all([ 
    obj1.save(), 
    obj2.save(), 
    obj3.save() 
]) 
.then(console.log) 
.catch(console.error) 

実際には、あなたはArray.map()ここに使用することができます。

Promise.all([ obj1, obj2, obj3 ].map(obj => obj.save()) 

AAANDも結果の配列destructureするES6の構文を使用します。

Promise.all([ obj1, obj2, obj3 ].map(obj => obj.save()) 
.then(([ savedObj1, savedObj2, savedObj3 ]) => { 
    // do something with your saved objects... 
}) 
関連する問題