Mongoose JS promises? Or how to manage batch save
Yes, you can do this with promises. If you were using the Q promise library, you could re-write @matz3's code like:
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); });
We start all the operations one at a time in the loop, but we don't wait for any of them to complete, so they run in parallel. We add a promise (that acts like a placeholder for the result) to an array. We then wait for all the promises in the array of promises to complete.
Most good Promises/A+ compatible libraries have some equivalent to Q.all
mongoose now allows you to choose which Promise implementation.
Here I am using the node.js default system Promise (ES6) baked into nodejs
var mongoose = require('mongoose'); mongoose.Promise = global.Promise; // use system implementationPromise.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();});
node --versionv4.1.1
mongoose@4.1.8
Since mongoose
now supports promises you may use Promise.all().then()
, so it will return when all promises are resolved.
Promise.all([ obj1.save(), obj2.save(), obj3.save()]).then(console.log).catch(console.error)
In fact, if you're always calling the save()
method you can use the Array.map()
here:
Promise.all([ obj1, obj2, obj3 ].map( obj => obj.save() )
Aaand also use es6 syntax to destructure the resulting array:
Promise.all( [ obj1, obj2, obj3 ] .map( obj => obj.save() )).then( ([ savedObj1, savedObj2, savedObj3 ]) => { // do something with your saved objects...})