Backend half
This commit is contained in:
+235
@@ -0,0 +1,235 @@
|
||||
var AWS = require('./core');
|
||||
|
||||
/**
|
||||
* @api private
|
||||
* @!method on(eventName, callback)
|
||||
* Registers an event listener callback for the event given by `eventName`.
|
||||
* Parameters passed to the callback function depend on the individual event
|
||||
* being triggered. See the event documentation for those parameters.
|
||||
*
|
||||
* @param eventName [String] the event name to register the listener for
|
||||
* @param callback [Function] the listener callback function
|
||||
* @param toHead [Boolean] attach the listener callback to the head of callback array if set to true.
|
||||
* Default to be false.
|
||||
* @return [AWS.SequentialExecutor] the same object for chaining
|
||||
*/
|
||||
AWS.SequentialExecutor = AWS.util.inherit({
|
||||
|
||||
constructor: function SequentialExecutor() {
|
||||
this._events = {};
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
listeners: function listeners(eventName) {
|
||||
return this._events[eventName] ? this._events[eventName].slice(0) : [];
|
||||
},
|
||||
|
||||
on: function on(eventName, listener, toHead) {
|
||||
if (this._events[eventName]) {
|
||||
toHead ?
|
||||
this._events[eventName].unshift(listener) :
|
||||
this._events[eventName].push(listener);
|
||||
} else {
|
||||
this._events[eventName] = [listener];
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
onAsync: function onAsync(eventName, listener, toHead) {
|
||||
listener._isAsync = true;
|
||||
return this.on(eventName, listener, toHead);
|
||||
},
|
||||
|
||||
removeListener: function removeListener(eventName, listener) {
|
||||
var listeners = this._events[eventName];
|
||||
if (listeners) {
|
||||
var length = listeners.length;
|
||||
var position = -1;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
if (listeners[i] === listener) {
|
||||
position = i;
|
||||
}
|
||||
}
|
||||
if (position > -1) {
|
||||
listeners.splice(position, 1);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
removeAllListeners: function removeAllListeners(eventName) {
|
||||
if (eventName) {
|
||||
delete this._events[eventName];
|
||||
} else {
|
||||
this._events = {};
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
emit: function emit(eventName, eventArgs, doneCallback) {
|
||||
if (!doneCallback) doneCallback = function() { };
|
||||
var listeners = this.listeners(eventName);
|
||||
var count = listeners.length;
|
||||
this.callListeners(listeners, eventArgs, doneCallback);
|
||||
return count > 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
callListeners: function callListeners(listeners, args, doneCallback, prevError) {
|
||||
var self = this;
|
||||
var error = prevError || null;
|
||||
|
||||
function callNextListener(err) {
|
||||
if (err) {
|
||||
error = AWS.util.error(error || new Error(), err);
|
||||
if (self._haltHandlersOnError) {
|
||||
return doneCallback.call(self, error);
|
||||
}
|
||||
}
|
||||
self.callListeners(listeners, args, doneCallback, error);
|
||||
}
|
||||
|
||||
while (listeners.length > 0) {
|
||||
var listener = listeners.shift();
|
||||
if (listener._isAsync) { // asynchronous listener
|
||||
listener.apply(self, args.concat([callNextListener]));
|
||||
return; // stop here, callNextListener will continue
|
||||
} else { // synchronous listener
|
||||
try {
|
||||
listener.apply(self, args);
|
||||
} catch (err) {
|
||||
error = AWS.util.error(error || new Error(), err);
|
||||
}
|
||||
if (error && self._haltHandlersOnError) {
|
||||
doneCallback.call(self, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
doneCallback.call(self, error);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds or copies a set of listeners from another list of
|
||||
* listeners or SequentialExecutor object.
|
||||
*
|
||||
* @param listeners [map<String,Array<Function>>, AWS.SequentialExecutor]
|
||||
* a list of events and callbacks, or an event emitter object
|
||||
* containing listeners to add to this emitter object.
|
||||
* @return [AWS.SequentialExecutor] the emitter object, for chaining.
|
||||
* @example Adding listeners from a map of listeners
|
||||
* emitter.addListeners({
|
||||
* event1: [function() { ... }, function() { ... }],
|
||||
* event2: [function() { ... }]
|
||||
* });
|
||||
* emitter.emit('event1'); // emitter has event1
|
||||
* emitter.emit('event2'); // emitter has event2
|
||||
* @example Adding listeners from another emitter object
|
||||
* var emitter1 = new AWS.SequentialExecutor();
|
||||
* emitter1.on('event1', function() { ... });
|
||||
* emitter1.on('event2', function() { ... });
|
||||
* var emitter2 = new AWS.SequentialExecutor();
|
||||
* emitter2.addListeners(emitter1);
|
||||
* emitter2.emit('event1'); // emitter2 has event1
|
||||
* emitter2.emit('event2'); // emitter2 has event2
|
||||
*/
|
||||
addListeners: function addListeners(listeners) {
|
||||
var self = this;
|
||||
|
||||
// extract listeners if parameter is an SequentialExecutor object
|
||||
if (listeners._events) listeners = listeners._events;
|
||||
|
||||
AWS.util.each(listeners, function(event, callbacks) {
|
||||
if (typeof callbacks === 'function') callbacks = [callbacks];
|
||||
AWS.util.arrayEach(callbacks, function(callback) {
|
||||
self.on(event, callback);
|
||||
});
|
||||
});
|
||||
|
||||
return self;
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers an event with {on} and saves the callback handle function
|
||||
* as a property on the emitter object using a given `name`.
|
||||
*
|
||||
* @param name [String] the property name to set on this object containing
|
||||
* the callback function handle so that the listener can be removed in
|
||||
* the future.
|
||||
* @param (see on)
|
||||
* @return (see on)
|
||||
* @example Adding a named listener DATA_CALLBACK
|
||||
* var listener = function() { doSomething(); };
|
||||
* emitter.addNamedListener('DATA_CALLBACK', 'data', listener);
|
||||
*
|
||||
* // the following prints: true
|
||||
* console.log(emitter.DATA_CALLBACK == listener);
|
||||
*/
|
||||
addNamedListener: function addNamedListener(name, eventName, callback, toHead) {
|
||||
this[name] = callback;
|
||||
this.addListener(eventName, callback, toHead);
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
addNamedAsyncListener: function addNamedAsyncListener(name, eventName, callback, toHead) {
|
||||
callback._isAsync = true;
|
||||
return this.addNamedListener(name, eventName, callback, toHead);
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper method to add a set of named listeners using
|
||||
* {addNamedListener}. The callback contains a parameter
|
||||
* with a handle to the `addNamedListener` method.
|
||||
*
|
||||
* @callback callback function(add)
|
||||
* The callback function is called immediately in order to provide
|
||||
* the `add` function to the block. This simplifies the addition of
|
||||
* a large group of named listeners.
|
||||
* @param add [Function] the {addNamedListener} function to call
|
||||
* when registering listeners.
|
||||
* @example Adding a set of named listeners
|
||||
* emitter.addNamedListeners(function(add) {
|
||||
* add('DATA_CALLBACK', 'data', function() { ... });
|
||||
* add('OTHER', 'otherEvent', function() { ... });
|
||||
* add('LAST', 'lastEvent', function() { ... });
|
||||
* });
|
||||
*
|
||||
* // these properties are now set:
|
||||
* emitter.DATA_CALLBACK;
|
||||
* emitter.OTHER;
|
||||
* emitter.LAST;
|
||||
*/
|
||||
addNamedListeners: function addNamedListeners(callback) {
|
||||
var self = this;
|
||||
callback(
|
||||
function() {
|
||||
self.addNamedListener.apply(self, arguments);
|
||||
},
|
||||
function() {
|
||||
self.addNamedAsyncListener.apply(self, arguments);
|
||||
}
|
||||
);
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* {on} is the prefered method.
|
||||
* @api private
|
||||
*/
|
||||
AWS.SequentialExecutor.prototype.addListener = AWS.SequentialExecutor.prototype.on;
|
||||
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
module.exports = AWS.SequentialExecutor;
|
||||
Reference in New Issue
Block a user