Created
February 2, 2016 07:09
-
-
Save jeroenransijn/d83c8ec1058dd6f67063 to your computer and use it in GitHub Desktop.
Events.es2015.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Class representing an events interface similar to EventEmitter/Backbone.Events | |
* @author Jeroen Ransijn [@Jeroen_Ransijn] | |
* @example | |
* const events = new Events(); | |
* | |
* events.on('change', (...args) => { console.log(args); }); | |
* events.trigger('change', 'firstArg', 'secondArg'); | |
* // Returns ['firstArg', 'secondArg'] | |
* | |
* events.onAll((key, ...args) => { console.log(key, args); }); | |
* events.trigger('randomKey'); | |
* // Returns 'randomKey', ['firstArg', 'secondArg'] | |
*/ | |
export default class Events { | |
/** | |
* Create an events interface. | |
* Sets two properties on this instance | |
* @property {Map.<Array[Function]>} listeners | |
* @property {Array.<Function>} globalListeners | |
*/ | |
constructor () { | |
this.listeners = new Map(); | |
this.globalListeners = []; | |
} | |
/** | |
* Adds listener(s) to an event by key | |
* @param {*} key - name of the event | |
* @param {...Function} listeners - callbacks (...args) to call when the event is triggered | |
* @return this | |
*/ | |
on (key, ...listeners) { | |
if (this.listeners.has(key)) { | |
const newListeners = this.listeners.get(key); | |
newListeners.push(...listeners); | |
this.listeners.set(key, newListeners); | |
} else { | |
this.listeners.set(key, [...listeners]); | |
} | |
return this; | |
} | |
/** | |
* Adds listener(s) to all events that will ever by triggered | |
* @param {...Function} listeners - callbacks (key, ...args) to call on all events triggered | |
* @return this | |
*/ | |
onAll (...listeners) { | |
this.globalListeners.push(...listeners); | |
return this; | |
} | |
/** | |
* Remove listener(s) from an event by key | |
* Remove all listeners from an event if no listeners are passed | |
* @param {*} key - name of the events | |
* @param {...Function} listeners - callbacks to remove from the event | |
* @return this | |
*/ | |
off (key, ...listeners) { | |
if (!this.listeners.has(key)) return this; | |
if (listeners) { | |
// Only remove the listeners passed if any are passed | |
this.listeners.set(key, | |
this.listeners.get(key).filter((listener) => listeners.find((x) => x !== listener)) | |
); | |
if (this.listeners.get(key).length === 0) { | |
// Remove the key if there are no more listeners | |
this.listeners.delete(key); | |
} | |
} else { | |
this.listeners.delete(key); | |
} | |
return this; | |
} | |
/** | |
* Trigger all listener(s) for an events | |
* @param {*} key - name of the event | |
* @param {...*} args - arguments to be applied on the listeners | |
* @return this | |
*/ | |
trigger (key, ...args) { | |
this.globalListeners.forEach((listener) => listener(key, ...args)); | |
if (!this.listeners.has(key)) return this; | |
this.listeners.get(key).forEach((listener) => listener(...args)); | |
return this; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { expect } from 'chai'; | |
import Events from './Events'; | |
describe('Events', () => { | |
const events = new Events(); | |
var stringData; | |
const stringKey = 'stringKey'; | |
const stringKeyListener = (data) => { | |
// Set a state we can confirm | |
stringData = data | |
}; | |
const symbolKey = Symbol('symbolKey'); | |
const symbolKeyListener = () => {}; | |
const objectKey = { random: 'contents' }; | |
it('creates two instance properties', () => { | |
expect(events.listeners).to.be.a('map'); | |
expect(events.globalListeners).to.be.a('array'); | |
}); | |
it('can add a listener with a string as a key', () => { | |
events.on(stringKey, stringKeyListener); | |
expect(events.listeners.has(stringKey)).to.be.true; | |
}); | |
it('can add a listener with a symbol as a key', () => { | |
events.on(symbolKey, symbolKeyListener); | |
expect(events.listeners.has(symbolKey)).to.be.true; | |
}); | |
it('can add a listener with an object as a key', () => { | |
const listener = () => {}; | |
events.on(objectKey, listener); | |
expect(events.listeners.has(objectKey)).to.be.true; | |
}); | |
it('can add another listener for a key', () => { | |
events.on(stringKey, () => {}); | |
expect(events.listeners.get(stringKey)).to.be.a('array'); | |
expect(events.listeners.get(stringKey).length).to.equal(2); | |
}); | |
it('can add and trigger a global listener with onAll', () => { | |
var outerState = false; | |
var outerParam1; | |
var outerParam2; | |
const randomParam1Value = 'randomParam1'; | |
const randomParam2Value = 'randomParam2'; | |
const listener = (eventName, ...args) => { | |
outerState = true; | |
outerParam1 = args[0]; | |
outerParam2 = args[1]; | |
}; | |
events.onAll(listener); | |
events.trigger('randomKey', randomParam1Value, randomParam2Value); | |
expect(outerState).to.be.true; | |
expect(outerParam1).to.equal(randomParam1Value); | |
expect(outerParam2).to.equal(randomParam2Value); | |
}); | |
it('can trigger a listener', () => { | |
const data = { isHere: true }; | |
events.trigger(stringKey, data); | |
expect(stringData).to.equal(data); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment