Built-in Promises
Mongoose async operations, like .save()
and queries, return
Promises/A+ conformant promises.
This means that you can do things like MyModel.findOne({}).then()
and
yield MyModel.findOne({}).exec()
(if you're using co).
For backwards compatibility, Mongoose 4 returns mpromise promises by default.
var gnr = new Band({
name: "Guns N' Roses",
members: ['Axl', 'Slash']
});
var promise = gnr.save();
assert.ok(promise instanceof require('mpromise'));
promise.then(function (doc) {
assert.equal(doc.name, "Guns N' Roses");
});
Queries are not promises
Mongoose queries are not promises. However, they do have a .then()
function for yield
and async/await. If you need
a fully-fledged promise, use the .exec()
function.
var query = Band.findOne({name: "Guns N' Roses"});
assert.ok(!(query instanceof require('mpromise')));
// A query is not a fully-fledged promise, but it does have a `.then()`.
query.then(function (doc) {
// use doc
});
// `.exec()` gives you a fully-fledged promise
var promise = query.exec();
assert.ok(promise instanceof require('mpromise'));
promise.then(function (doc) {
// use doc
});
Plugging in your own Promises Library
New in Mongoose 4.1.0
While mpromise is sufficient for basic use cases, advanced users
may want to plug in their favorite
ES6-style promises library
like bluebird, or just use
native ES6 promises. Just set mongoose.Promise
to your favorite
ES6-style promise constructor and mongoose will use it.
Mongoose tests with ES6 native promises, bluebird, and q. Any promise library that exports an ES6-style promise constructor should work in theory, but theory often differs from practice. If you find a bug, open an issue on GitHub
var query = Band.findOne({name: "Guns N' Roses"});
// Use native promises
mongoose.Promise = global.Promise;
assert.equal(query.exec().constructor, global.Promise);
// Use bluebird
mongoose.Promise = require('bluebird');
assert.equal(query.exec().constructor, require('bluebird'));
// Use q. Note that you **must** use `require('q').Promise`.
mongoose.Promise = require('q').Promise;
assert.ok(query.exec() instanceof require('q').makePromise);
Promises for the MongoDB Driver
The mongoose.Promise
property sets the promises mongoose uses. However,
this does not affect the underlying MongoDB driver. If you use the
underlying driver, for instance Model.collection.db.insert()
, you
need to do a little extra work to change the underlying promises library.
Note that the below code assumes mongoose >= 4.4.4.
var uri = 'mongodb://localhost:27017/mongoose_test';
// Use bluebird
var options = { promiseLibrary: require('bluebird') };
var db = mongoose.createConnection(uri, options);
Band = db.model('band-promises', { name: String });
db.on('open', function() {
assert.equal(Band.collection.findOne().constructor, require('bluebird'));
});