Skip to content

Commit

Permalink
Merge branch 'feat/async-listeners'
Browse files Browse the repository at this point in the history
  • Loading branch information
DigitalBrainJS committed May 2, 2020
2 parents 39c4a9b + 7f68f15 commit b7da98f
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 18 deletions.
31 changes: 24 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@ Fastest is EventEmitter2

### Differences (Non-breaking, compatible with existing EventEmitter)

- The EventEmitter2 constructor takes an optional configuration object.

- The EventEmitter2 constructor takes an optional configuration object with the following default values:
```javascript
var EventEmitter2 = require('eventemitter2').EventEmitter2;
var server = new EventEmitter2({
var EventEmitter2 = require('eventemitter2');
var emitter = new EventEmitter2({

// set this to `true` to use wildcards
wildcard: false,
Expand Down Expand Up @@ -155,7 +154,7 @@ $ npm install eventemitter2

- [getMaxListeners(): number](#emittergetmaxlisteners)

- [eventNames(): string[]](#emittereventnames)
- [eventNames(nsAsArray?: boolean): string[]](#emittereventnamesnsasarray)

- [listeners(event: event | eventNS): ListenerFn[]](#emitterlistenersevent--eventns)

Expand Down Expand Up @@ -594,11 +593,11 @@ emitter.waitFor('event', {
emitter.emit('event', new Error('custom error')); // reject the promise
````
### emitter.eventNames()
### emitter.eventNames(nsAsArray)
Returns an array listing the events for which the emitter has registered listeners. The values in the array will be strings.
```javascript
var emitter= new EventEmitter2();
emitter.on('foo', () => {});
emitter.on('bar', () => {});

Expand Down Expand Up @@ -678,6 +677,24 @@ Checks whether emitter has any listeners.
### emitter.listeners(event | eventNS)
Returns the array of listeners for the event named eventName.
In wildcard mode this method returns namespaces as strings:
````javascript
var emitter= new EventEmitter2({
wildcard: true
});
emitter.on('a.b.c', function(){});
emitter.on(['z', 'x', 'c'], function(){});
console.log(emitter.eventNames()) // [ 'z.x.c', 'a.b.c' ]
````
If some namespace contains a Symbol member or the `nsAsArray` option is set the method will return namespace as an array of its members;
````javascript
var emitter= new EventEmitter2({
wildcard: true
});
emitter.on('a.b.c', function(){});
emitter.on(['z', 'x', Symbol()], function(){});
console.log(emitter.eventNames()) // [ [ 'z', 'x', Symbol() ], 'a.b.c' ]
````
### EventEmitter2.once(emitter, event | eventNS, [options])
Creates a cancellable Promise that is fulfilled when the EventEmitter emits the given event or that is rejected
Expand Down
2 changes: 1 addition & 1 deletion eventemitter2.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export declare class EventEmitter2 {
removeAllListeners(event?: event | eventNS): this;
setMaxListeners(n: number): void;
getMaxListeners(): number;
eventNames(): string[];
eventNames(nsAsArray?: boolean): (event|eventNS)[];
listenerCount(event?: event | eventNS): number
listeners(event?: event | eventNS): ListenerFn[]
listenersAny(): ListenerFn[]
Expand Down
34 changes: 32 additions & 2 deletions lib/eventemitter2.js
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,36 @@
return true;
}

function collectTreeEvents(tree, events, root, asArray){
var branches= ownKeys(tree);
var i= branches.length;
var branch, branchName, path;
var hasListeners= tree['_listeners'];
var isArrayPath;

while(i-->0){
branchName= branches[i];

branch= tree[branchName];

if(branchName==='_listeners'){
path= root;
}else {
path = root ? root.concat(branchName) : [branchName];
}

isArrayPath= asArray || typeof branchName==='symbol';

hasListeners && events.push(isArrayPath? path : path.join(this.delimiter));

if(typeof branch==='object'){
collectTreeEvents.call(this, branch, events, path, isArrayPath);
}
}

return events;
}

function recursivelyGarbageCollect(root) {
if (!root) {
return;
Expand Down Expand Up @@ -1312,9 +1342,9 @@
}
};

EventEmitter.prototype.eventNames = function(){
EventEmitter.prototype.eventNames = function(nsAsArray){
var _events= this._events;
return _events? ownKeys(_events) : [];
return this.wildcard? collectTreeEvents.call(this, this.listenerTree, [], null, nsAsArray) : (_events? ownKeys(_events) : []);
};

EventEmitter.prototype.listenerCount = function(type) {
Expand Down
8 changes: 0 additions & 8 deletions test/perf/package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
{
"name": "benchmarks",
"version": "0.0.0",
"description": "eventemitter3 benchmarks",
"main": "index.js",
"scripts": {
"benchmark": "find run -name '*.js' -exec ./start.sh {} \\;"
},
"repository": "primus/eventemitter3",
"author": "Arnout Kazemier",
"license": "MIT",
"dependencies": {
"benchmark": "2.1.x",
"eventemitter3": "latest"
Expand Down
13 changes: 13 additions & 0 deletions test/simple/emit.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,18 @@ module.exports = simpleEvents({
test.done();
},

'8. Emit event with more than 2 arguments': function (test) {
var emitter = new EventEmitter2({ verbose: true });

emitter.on('test', function(x,y,z){
test.equal(x, 1);
test.equal(y, 2);
test.equal(z, 3);
});

emitter.emit('test', 1, 2, 3);
test.expect(3);
test.done();
}
});

53 changes: 53 additions & 0 deletions test/wildcardEvents/eventsNames.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
var assert = require('assert');
var file = '../../lib/eventemitter2';
var EventEmitter2;

if (typeof require !== 'undefined') {
EventEmitter2 = require(file).EventEmitter2;
} else {
EventEmitter2 = window.EventEmitter2;
}

module.exports = {
'1. should return wildcard events namespaces': function () {
var symbol= Symbol('test');

var ee= new EventEmitter2({
wildcard: true
});

var listener;

ee.on('a.b.c', function(){});
ee.on('a.b.d', listener= function(){});
ee.on('z.*', function(){});
ee.on(['a', 'b', symbol], function(){});

assert.deepEqual(ee.eventNames(), [ 'z.*', [ 'a', 'b', symbol ], 'a.b.d', 'a.b.c' ]);

ee.off('a.b.d', listener);

assert.deepEqual(ee.eventNames(), [ 'z.*', [ 'a', 'b', symbol ], 'a.b.c' ]);
},

'2. should return wildcard events namespaces as array if asArray option was set': function () {
var symbol= Symbol('test');

var ee= new EventEmitter2({
wildcard: true
});

var listener;

ee.on('a.b.c', function(){});
ee.on('a.b.d', listener= function(){});
ee.on('z.*', function(){});
ee.on(['a', 'b', symbol], function(){});

assert.deepEqual(ee.eventNames(true), [ ['z','*'], [ 'a', 'b', symbol ], ['a','b','d'], ['a','b','c']]);

ee.off('a.b.d', listener);

assert.deepEqual(ee.eventNames(true), [ ['z','*'], [ 'a', 'b', symbol ], ['a','b','c']]);
}
};
34 changes: 34 additions & 0 deletions test/wildcardEvents/removeAllListeners.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
var assert= require('assert');

var file = '../../lib/eventemitter2';
var EventEmitter2;

if(typeof require !== 'undefined') {
EventEmitter2 = require(file).EventEmitter2;
}
else {
EventEmitter2 = window.EventEmitter2;
}

module.exports= {
'should remove all wildcard events': function(){
var counter=0;

var ee= new EventEmitter2({
wildcard: true
});

ee.on('test.*', function(){
counter++;
});

assert.equal(ee.listenerCount('test.*'), 1);

ee.emit('test.foo');

assert.equal(counter, 1);
ee.removeAllListeners();

assert.equal(ee.listenerCount('test.*'), 0);
}
};

0 comments on commit b7da98f

Please sign in to comment.