diff --git a/common/lib/util/eventemitter.js b/common/lib/util/eventemitter.js index b503ccfc4c..48f45ac647 100644 --- a/common/lib/util/eventemitter.js +++ b/common/lib/util/eventemitter.js @@ -186,7 +186,16 @@ var EventEmitter = (function() { } else if(Utils.isEmptyArg(event)) { this.anyOnce.push(listener); } else if(Utils.isArray(event)){ - throw("Arrays of events can only be used with on(), not once()"); + var listenerWrapper = function() { + var args = Array.prototype.slice.call(arguments); + Utils.arrForEach(event, function(ev) { + self.off(ev, listenerWrapper); + }); + listener.apply(this, args); + }; + Utils.arrForEach(event, function(ev) { + self.on(ev, listenerWrapper); + }); } else { var listeners = (this.eventsOnce[event] || (this.eventsOnce[event] = [])); listeners.push(listener); diff --git a/spec/realtime/event_emitter.test.js b/spec/realtime/event_emitter.test.js index b0fee9ecaa..ba8bb4553a 100644 --- a/spec/realtime/event_emitter.test.js +++ b/spec/realtime/event_emitter.test.js @@ -342,6 +342,31 @@ define(['shared_helper', 'chai'], function (helper, chai) { closeAndFinish(done, realtime); }); + it('arrayOfEventsWithOnce', function (done) { + var realtime = helper.AblyRealtime({ autoConnect: false }), + callbackCalled = 0, + eventEmitter = realtime.connection; + + var callback = function (arg) { + callbackCalled += 1; + expect(arg).to.equal('expected'); + }; + + try { + callbackCalled = 0; + eventEmitter.once(['a', 'b', 'c'], callback); + eventEmitter.emit('a', 'expected'); + eventEmitter.emit('b', 'wrong'); + eventEmitter.emit('c', 'wrong'); + expect(callbackCalled).to.equal(1, 'listener called back only once, for the first event emitted'); + } catch (err) { + closeAndFinish(done, realtime, err); + return; + } + + closeAndFinish(done, realtime); + }); + /* check that listeners added in a listener cb are not called during that * emit instance */ it('listenerAddedInListenerCb', function (done) {