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( async.eachSeries(
observers, 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) } function(err) { callback(err, context) }
); );
}); });

View File

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

View File

@ -1,5 +1,6 @@
var ModelBuilder = require('../').ModelBuilder; var ModelBuilder = require('../').ModelBuilder;
var should = require('./init'); var should = require('./init');
var Promise = global.Promise || require('bluebird');
describe('async observer', function() { describe('async observer', function() {
var TestModel; var TestModel;
@ -93,6 +94,27 @@ describe('async observer', function() {
done(); 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) { function pushAndNext(array, value) {