ModelBaseClass: support promise-based observers

Allow the observer functions passed to `ModelBaseClass.observe`
to return a promise instead of calling the callback.
This commit is contained in:
Miroslav Bajtoš 2015-02-17 17:31:42 +01:00
parent a44e45b30a
commit a2836fbb56
3 changed files with 32 additions and 1 deletions

View File

@ -567,7 +567,15 @@ ModelBaseClass.notifyObserversOf = function(operation, context, callback) {
async.eachSeries(
observers,
function(fn, next) { fn(context, next); },
function notifySingleObserver(fn, next) {
var retval = fn(context, next);
if (retval && typeof retval.then === 'function') {
retval.then(
function() { next(); },
next // error handler
);
}
},
function(err) { callback(err, context) }
);
});

View File

@ -23,6 +23,7 @@
"node >= 0.6"
],
"devDependencies": {
"bluebird": "^2.9.9",
"mocha": "^2.1.0",
"should": "^5.0.0"
},

View File

@ -1,5 +1,6 @@
var ModelBuilder = require('../').ModelBuilder;
var should = require('./init');
var Promise = global.Promise || require('bluebird');
describe('async observer', function() {
var TestModel;
@ -93,6 +94,27 @@ describe('async observer', function() {
done();
});
});
it('resolves promises returned by observers', function(done) {
TestModel.observe('event', function(ctx) {
return Promise.resolve('value-to-ignore');
});
TestModel.notifyObserversOf('event', {}, function(err, ctx) {
// the test times out when the promises are not supported
done();
});
});
it('handles rejected promise returned by an observer', function(done) {
var testError = new Error('expected test error');
TestModel.observe('event', function(ctx) {
return Promise.reject(testError);
});
TestModel.notifyObserversOf('event', {}, function(err, ctx) {
err.should.eql(testError);
done();
});
});
});
function pushAndNext(array, value) {