Я тоже столкнулся с этой проблемой. Я бы подумал, что предпочтительный способ справиться с этим будет с событиями, однако при просмотре исходного кода там, кажется, не было ничего, что держало бы некоторый тип подсчета операций. В итоге я подключил его к EventEmitter. Что было бы лучше, так это если бы Mongoose генерировал события до и после сохранения, чтобы мне не пришлось подключать это ко всем моим моделям.
Вот пример того, как я это сделал:
/* lib/render_log.js */
/* Model for managing RenderLog */
var common = require("./common");
common.initialize_locals(global);
var mongoose = require("mongoose"),
Schema = mongoose.Schema;
var RenderLogSchema = new Schema({
renderer: String,
template: String,
content: {}
});
RenderLogSchema.pre('save', function(next){
this.db.model('RenderLog').emit('open_db_op', this);
next();
});
RenderLogSchema.post('save', function(){
this.db.model('RenderLog').emit('close_db_op', this);
});
mongoose.connect('mongodb://localhost/time-jr-development');
var RenderLog = mongoose.model("RenderLog", RenderLogSchema);
exports = module.exports = RenderLog;
Вслед за моим исполняемым файлом теста:
/* bin/test_mongoose.js */
var async = require('async');
var RenderLog = require("../lib/render_log");
var ConnectionManager = {
open_db_ops: 0,
new_db_op: function(){
this.open_db_ops ++;
},
close_db_op: function(){
this.open_db_ops --;
},
close: function(self){
if(!self)
self = this;
if(self.open_db_ops > 0){
console.log("Waiting...")
process.nextTick(async.apply(self.close, self));
}else{
RenderLog.db.close();
}
}
};
RenderLog.on("open_db_op", function(model){
ConnectionManager.new_db_op();
});
RenderLog.on("close_db_op", function(model){
ConnectionManager.close_db_op();
})
new RenderLog({renderer: "foo", template: "foo.html", content: {"bar": 1}}).save();
new RenderLog({renderer: "foo", template: "foo.html", content: {"bar": 2}}).save();
new RenderLog({renderer: "foo", template: "foo.html", content: {"bar": 3}}).save();
new RenderLog({renderer: "foo", template: "foo.html", content: {"bar": 4}}).save();
new RenderLog({renderer: "foo", template: "foo.html", content: {"bar": 5}}).save();
// You have to push this to the next tick otherwise it gets called before the save
// events have been emitted
async.nextTick(async.apply(ConnectionManager.close, ConnectionManager));