Middleware
Middleware are functions which are passed control of flow during execution of init, validate, save and remove methods.
There are two types of middleware, serial and parallel.
Serial
Serial middleware are executed one after another, when each middleware calls next
var schema = new Schema(..);
schema.pre('save', function (next) {
  // do stuff
  next();
});Parallel
Parallel middleware offer more fine-grained flow control.
var schema = new Schema(..);
schema.pre('save', true, function (next, done) {
  // calling next kicks off the next middleware in parallel
  next();
  doAsync(done);
});The hooked method, in this case save, will not be executed until done is called by each middleware.
Use Cases
Middleware are useful for atomizing model logic and avoiding nested blocks of async code. Here are some other ideas:
- complex validation
- removing dependent documents- (removing a user removes all his blogposts)
 
- asynchronous defaults
- asynchronous tasks that a certain action triggers- triggering custom events
- notifications
 
Error handling
If any middleware calls next or done with an Error instance, the flow is interrupted, and the error is passed to the callback.
schema.pre('save', function (next) {
  var err = new Error('something went wrong');
  next(err);
});
// later...
myModel.save(function (err) {
  console.log(err.message) // something went wrong
});
