arc-events
ES6 EventEmitter class with advanced features
Install
$ npm install arc-events --save
Features
- Classic on/once/emit methods
- onState/emitState for behavior around boolean states (ie. Loaded)
- Can be initialized independently
- Static mixin method for easily extending existing objects
- CatchAll and catch events without listeners
- Catch to catch potentially important events before a listener has been bound
- Optional id based management for easier cleanup
Basic Usage
The following creates a new ArcEvents
object and listens for an event, and fires an event
var ArcEvents = require('arc-events');
let CustomEmitter = new ArcEvents();
CustomEmitter.on('change',function(_data1,_data2){
});
CustomEmitter.emit('change',['arg1','arg2']);
Advanced Usage
In certain edge cases, a basic EventEmitter may not suffice, the following examples highlight some more common contexts.
Example 1: Timing
It is possible inside of certain abstractions, that an async data source may be receive data before the system is ready to listen for that data. In these cases setCatch()
can be used, to catch an event internally until a listener is bound to the object.
var ArcEvents = require('arc-events');
var EventEmitter = new ArcEvents();
EventEmitter.setCatch('data');
var Data = ASYNC_DATA;
setInterval(function(){
while(Data.buffer()){
EventEmitter.emit('data',[Data.read()]);
}
},250);
EventEmitter.on('data',function(_data){
});
Example 2: Unknown/Dynamic Events
In a service consumer, if the service is providing events dynamically, unknown events may be critical and should be handle even if they are not actively listened for. In this way setCatchAll()
can be used to ensure no events are missed.
var REST = RESTFUL_CONSUMER;
REST.on(200,function(_Response){
});
REST.on(500,function(_Response){
});
REST.setCatchAll(function(_event,_Response){
});
Example 3: Optimal Binary States
Classically EventEmitters have a linear relationship: a listener is bound, and events fired after the listener is bound trigger the listener. If the listener is removed, those same events no longer trigger it, if another listener is added, all listeners fire chronologically in the order bound.
This is non optimal for binary states, such as loaded, or ready, or other similarily used states. In these cases, ideal behavior changes to the following:
- Bind a listener to a binary state
- Assume all listeners are of the type 'once'
- IF the state is already in the desired state, do not bind the listener at all, simply fire it immediately
ArcEvents supports this type of behavior with the onState()
and emitState()
methods;
var Scripts = SCRIPT_LOADER;
Scripts.onState('specialScriptLoaded',function(){
});
(function(_Scripts){
_Scripts.emitState('specialScriptLoaded');
})(Scripts);
Scripts.onState('specialScriptLoaded',function(){
});
API
new ArcEvents()
Create a new ArcEvents
object. Requires new
.clear()
Clears the EventEmitter back to it's original state, effectively a reset
for the Emitter.
.setCatchAll(listener:Function
)
Set a special listener to catch all events that do not have any listener bound. Can be unset by passing undefined
as the listener argument.
.setCatch(event:String
)
Tell the EventEmitter to collect all emitted events of a certain type. These events will be stored internally until a listener is bound, at which point the listener will be called chronologically for each stored event, clearing it out of the EventEmitter.
.on(event:String, listener:Function [,customId:Mixed]
)
Set a callback to listen for an event being emitted. customId is an optional id, that can technically be anything that in turn can be used by the clean()
method later to clear all listeners matching that id. In the event that no customId is set on()
will return an id that was internally generated.
.onState(state:String,listener:Function
)
Set a callback to listen for a state. If that state already exists, the listener will not be bound internally and simply immediately fire, otherwise it will be bound internally until the state is emitted at which point it will be fired and cleared.
.checkState(state:String
)
Check to see whether a state has fired. Returns true
or false
.once(event:String, listener:Function [,customId:Mixed]
)
Set a callback to listen for an event being emitted. When the listener fires, it will automatically be removed internally as a listener and will no longer fire on subsequent events.
.removeListener(event:String, listener:Function
)
.clean(customId:Mixed
)
These methods are for cleanup:
removeListener()
requires the original function to remove the listenerclean()
uses an id to remove the listener
var ArcEvents = require('arc-events');
var eventEmitter = new ArcEvents();
var listener = function(){
};
eventEmitter.on('event',listener);
eventEmitter.removeListener('event',listener);
var internalId = eventEmitter.on('event',function(){
});
eventEmitter.clean(internalId);
.removeAllListeners(event:String
)
If a string
is passed in, remove all listeners for that event. If undefined
is passed in, remove all internal listeners.
.getListeners(event:String
)
Get an array of all listeners bound to an event.
.emit(event:String [,arguments:Array]
)
Emit an event, in order to trigger all listeners bound to the event. Arguments is an optional array of the argument list that will be passed into the listener.
.emitState(state:String
)
Emit a state and trigger/clear all listeners bound to that state. Additionally set the internal state to true
allowing future onState()
listeners to immediately fire.
.clearState(state:String
)
Clear a state, allowing listeners to once more be bound internally waiting for the state to fire.
ArcEvents.mixin(target:Object
)
A static method for extending existing objects. Existing object will have all of the ArcEvents methods bound to it, and will overwrite properties that are already set that have the same name.
var ArcEvents = require('arc-events');
var OtherClass = new OtherClass();
ArcEvents.mixin(OtherClass);
OtherClass.on('what?',()=>{});
OtherClass.emit('what?');
Testing
$ npm test