diff --git a/lib/model.js b/lib/model.js index 417e9471..f2d4615c 100644 --- a/lib/model.js +++ b/lib/model.js @@ -600,6 +600,30 @@ ModelBaseClass.observe = function(operation, listener) { this._observers[operation].push(listener); }; +/** + * Unregister an asynchronous observer for the given operation (event). + * @param {String} operation The operation name. + * @callback {function} listener The listener function. + * @end + */ +ModelBaseClass.removeObserver = function(operation, listener) { + if (!this._observers[operation]) return; + + var index = this._observers[operation].indexOf(listener); + if (index != -1) this._observers[operation].splice(index, 1); +}; + +/** + * Unregister all asynchronous observers for the given operation (event). + * @param {String} operation The operation name. + * @end + */ +ModelBaseClass.clearObservers = function(operation) { + if (!this._observers[operation]) return; + + this._observers[operation].length = 0; +}; + /** * Invoke all async observers for the given operation. * @param {String} operation The operation name. diff --git a/test/async-observer.test.js b/test/async-observer.test.js index 3cb2dbdb..3786969e 100644 --- a/test/async-observer.test.js +++ b/test/async-observer.test.js @@ -79,6 +79,44 @@ describe('async observer', function() { }); }); + it('can remove observers', function(done) { + var notifications = []; + + function call(ctx, next) { + notifications.push('call'); + process.nextTick(next); + }; + + TestModel.observe('event', call); + TestModel.removeObserver('event', call); + + TestModel.notifyObserversOf('event', {}, function(err) { + if (err) return done(err); + notifications.should.eql([]); + done(); + }); + }); + + it('can clear all observers', function(done) { + var notifications = []; + + function call(ctx, next) { + notifications.push('call'); + process.nextTick(next); + }; + + TestModel.observe('event', call); + TestModel.observe('event', call); + TestModel.observe('event', call); + TestModel.clearObservers('event'); + + TestModel.notifyObserversOf('event', {}, function(err) { + if (err) return done(err); + notifications.should.eql([]); + done(); + }); + }); + it('handles no observers', function(done) { TestModel.notifyObserversOf('no-observers', {}, function(err) { // the test passes when no error was raised