_____ _ _ __
| ____|_ _____ _ __ | |_(_)/ _|_ _
| _| \ \ / / _ \ '_ \| __| | |_| | | |
| |___ \ V / __/ | | | |_| | _| |_| |
|_____| \_/ \___|_| |_|\__|_|_| \__, |
|___/
- Evented programming is essential to javascript; Eventify is a suitably capable events library
- The api for event declaration, emission and listening is consistent, plain and explicit
- Use first class language constructs instead of strings
var object = {};
eventify(object).define(
'onThis',
'onThat',
'onTheOther
);
eventify(obj)
is idempotent.
this.onSomeEvent.emit(123, 'some text', ['some', 'things']);
/*
emitting an that does not exist will fail fast compared to other event systems:
this.trigger('an-event', args) // quietly fails. unhelpful.
*/
var subscription = object.onThis(function () {
// event handling code here
// this === the source object
// arguments are those passed when the event was emitted
});
- returns object
- event listeners run in the context of object
subscription.cancel()
subscription.isActive()
subscirption.once()
(details below)subscirption.throttle()
(details below)
Call a listener no more than once every N milliseconds
object.onThis(function () { ... }).throttle(200);
The event behaves as a normal event for the first emission. Each successive emission within the throttle interval does not result in the listeners being called. When the throttle interval elapses, the listeners are called with the most recent arguments.
Scenario:
object.onThis(). emitInterval(1000);
object.onThis(function (i) {
console.info(i);
})
for(var i = 1; i <= 1000; i++) {
object.onThis().emit(i);
}
1
is written to the console immediately1000
is written to the console a second later
TODO: add a timeline here to make it clearer
The event listener will only be called the next time the event is emitted.
object.onThis(function () {
// only gets called on the next event omission
}).once();
// short for object.onThis(function () {...}).nTimes(1);
Some events such as onInit
, onLoad
, onReady
are only ever emitted once.
eventify(this).single('onInit');
After the first emission all subscriptions are cancelled. Any listeners added after the event has occurred can will be called on the next tick.
check is an event has occurred with object.onAnEvent.hasOccurred()
Each event has several methods intended to be used internally by the eventified object:
eventify(this).define('onSomeEvent')
this.onSomeEvent
now has:
eventName([{namespace: true}])
: returns the event name optionally with a namespace(more on namespaces later)subscriptions()
: aneventify.Subscriptions
subscription collection on which you can call:count()
toArray()
each(callback)
cancelAll()
emit(...)
: emit the event with any argumentsemitWithArgs(arrayOfArgs)
emitOnNextTick(...)
emitWithArgsOnNextTick(arrayOfArgs)
hasOccurred()
isSingle()
// pipe all events from some other object
eventify(this).pipe(source);
// or a subset...
eventify(this).pipe(source, 'onHighlight', 'onClick');
// map the events to a different name on this
eventify(this).pipe(source, 'onHighlight:onSelect', 'onClick:onPress');
/*
unlike define() and single() which return this.events, pipe() returns a collection of subscriptions to the source events which can be cancelled by calling subscriptions.cancelAll()...
*/
eventify(this).define(...);
var subscriptions = this.events.pipe(source, 'onClick:onOpen');
/*
calling subscriptions.cancelAll() results in the event emissions from source.onClick no longer being piped to this.onOpen
*/
eventify(this, 'my-namespace').define('onSomeEvent').single('onInit');
This gives you a way to listen to a 'class' of events.
eventify.listen({
'my-namespace/onSomeEvent': function (...) {
// this is the event source
}
, 'my-namespace/onInit': function () { ... }
});
This is how you can listen to the class of event my-namesapce/onSomeEvent
from any object
eventify.listen(function (event) {
/*
event looks like: {
source: ...
, eventName: 'my-namespace/onInit'
, args: ... // arguments object
}
*/
});
After an object is eventified it has an events member:
eventify(this);
this.events
now has:
define(...)
single(...)
pipe(originator, ...)
names()
: array of event namesnamespace()
: objects global namespacecancelAllSubscriptions()
: cancels all subscriptions to all events on the object
Further eventification on this
can be performed like so...
this.events.define('onOtherEvent').single('onTeardown')
- No guarantees are made about the order in which event listeners are called.