From aa2e57acc7a5e7c8642cb70c8862785ddfc220ca Mon Sep 17 00:00:00 2001 From: Ben Ripkens Date: Fri, 29 Jan 2016 11:14:04 +0100 Subject: [PATCH] Avoid memory leaks by remove event arrays When subscribing and then unsubscribing from many different types of events, it can be observed that the `Emitter._callbacks` object starts to grow. This happens because, when unsubscribing, the event specific event array is not removed when the last subscriber unsubscribes. --- index.js | 7 +++++++ test/emitter.js | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/index.js b/index.js index 1c78176..cb6a30a 100644 --- a/index.js +++ b/index.js @@ -109,6 +109,13 @@ Emitter.prototype.removeEventListener = function(event, fn){ break; } } + + // Remove event specific arrays for event types that no + // one is subscribed for to avoid memory leak. + if (callbacks.length === 0) { + delete this._callbacks['$' + event]; + } + return this; }; diff --git a/test/emitter.js b/test/emitter.js index 02c3a0b..a1f1dda 100644 --- a/test/emitter.js +++ b/test/emitter.js @@ -142,6 +142,32 @@ describe('Emitter', function(){ calls.should.eql([]); }) + + it('should remove event array to avoid memory leak', function() { + var emitter = new Emitter; + var calls = []; + + function cb() {} + + emitter.on('foo', cb); + emitter.off('foo', cb); + + emitter._callbacks.should.not.have.property('$foo'); + }) + + it('should only remove the event array when the last subscriber unsubscribes', function() { + var emitter = new Emitter; + var calls = []; + + function cb1() {} + function cb2() {} + + emitter.on('foo', cb1); + emitter.on('foo', cb2); + emitter.off('foo', cb1); + + emitter._callbacks.should.have.property('$foo'); + }) }) describe('.off()', function(){