carrack
Version:
a Promise-based EventEmitter
287 lines (227 loc) • 9.43 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _bluebird = require('bluebird');
var _bluebird2 = _interopRequireDefault(_bluebird);
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _events = require('events');
var _throat = require('throat');
var _throat2 = _interopRequireDefault(_throat);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // dependencies
// @class AsyncEmitter
var AsyncEmitter = function (_EventEmitter) {
_inherits(AsyncEmitter, _EventEmitter);
function AsyncEmitter() {
var concurrency = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
_classCallCheck(this, AsyncEmitter);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(AsyncEmitter).call(this));
if (concurrency >= 1) {
_this.setConcurrency(concurrency);
}
return _this;
}
/**
* reset concurrency of instance
*
* @method setConcurrency
* @param {number} [max=null] - a number of maximum concurrency
* @returns {asyncEmitter} this
*/
_createClass(AsyncEmitter, [{
key: 'setConcurrency',
value: function setConcurrency() {
var max = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
if (max >= 1) {
this.manager = (0, _throat2.default)(_bluebird2.default)(max);
} else {
this.manager = null;
}
return this;
}
/**
* run the listener as Promise
*
* @method executeListener
* @param {function} listener - a code block
* @param {any[]} args - a event arguments
* @returns {promise} - the return value or exception
*/
}, {
key: 'executeListener',
value: function executeListener(listener, args) {
try {
if (this.manager) {
return this.manager(function () {
return listener.apply(undefined, _toConsumableArray(args));
});
}
return _bluebird2.default.resolve(listener.apply(undefined, _toConsumableArray(args)));
} catch (error) {
return _bluebird2.default.reject(error);
}
}
/**
* run the listeners in parallel
*
* @method emitParallel
* @alias emit
* @param {string} event - a event name
* @param {any} arguments - a arguments pass to listeners
* @returns {promise<any>} - the return value of listeners
*/
}, {
key: 'emitParallel',
value: function emitParallel(event) {
var _this2 = this;
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
var promises = [];
this.listeners(event).forEach(function (listener) {
promises.push(_this2.executeListener(listener, args));
});
return _bluebird2.default.all(promises);
}
/**
* run the listeners in serial
*
* @method emitSerial
* @param {string} event - a event name
* @param {any} arguments - a arguments pass to listeners
* @returns {promise<any>} - the return value of listeners
*/
}, {
key: 'emitSerial',
value: function emitSerial(event) {
var _this3 = this;
for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
return this.listeners(event).reduce(function (promise, listener) {
return promise.then(function (values) {
return _this3.executeListener(listener, args).then(function (value) {
values.push(value);
return values;
});
});
}, _bluebird2.default.resolve([]));
}
/**
* run the listeners in serial using previous listener return value
*
* @method emitReduce
* @param {string} event - a event name
* @param {any} arguments - a arguments pass to listeners
* @returns {promise<any>} - the return value of listeners
*/
}, {
key: 'emitReduce',
value: function emitReduce(event) {
for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
args[_key3 - 1] = arguments[_key3];
}
return this.emitReduceRun(event, args);
}
/**
* run the listeners in serial and in inverse using previous listener return value
*
* @method emitReduceRight
* @param {string} event - a event name
* @param {any} arguments - a arguments pass to listeners
* @returns {promise<any>} - the return value of listeners
*/
}, {
key: 'emitReduceRight',
value: function emitReduceRight(event) {
for (var _len4 = arguments.length, args = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
args[_key4 - 1] = arguments[_key4];
}
return this.emitReduceRun(event, args, true);
}
/**
* emitReduce/emitReduceRight common processing
*
* @method emitReduceRun
* @param {string} event - a event name
* @param {any[]} args - a arguments pass to first listener
* @param {boolean} [inverse=false] - if true, execute listner in inverse
* @returns {any[]} values - the return value of last listener
*/
}, {
key: 'emitReduceRun',
value: function emitReduceRun(event, args) {
var _this4 = this;
var inverse = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
var listeners = inverse ? this.listeners(event).reverse() : this.listeners(event);
return listeners.reduce(function (promise, listener) {
return promise.then(function (prevArgs) {
var currentArgs = prevArgs instanceof Array ? prevArgs : [prevArgs];
return _this4.executeListener(listener, currentArgs);
});
}, _bluebird2.default.resolve(args));
}
/**
* emit a 'removeListener' event iff the listener was removed
* (redefine for inherited method doesn't work)
*
* @method once
* @param {string} event - a event name
* @param {function} listener - a listener function
* @returns {asyncEmitter} this
*/
}, {
key: 'once',
value: function once(event, listener) {
var _this5 = this;
if (typeof listener !== 'function') {
throw new TypeError('listener must be a function');
}
var fired = false;
var onceListener = function onceListener() {
_this5.removeListener(event, onceListener);
if (fired === false) {
fired = true;
return listener.apply(undefined, arguments);
}
return undefined;
};
// https://github.com/nodejs/node/blob/v4.1.2/lib/events.js#L286
onceListener.listener = listener;
this.on(event, onceListener);
return this;
}
/**
* register an event listener, returns the remove function
*
* @method subscribe
* @param {string} event - a event name
* @param {function} listener - a listener function
* @param {boolean} [once=false] - if true, listener is call only once
* @returns {function} unsubscribe - the remove function of listener
*/
}, {
key: 'subscribe',
value: function subscribe(event, listener) {
var _this6 = this;
var once = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
var unsubscribe = function unsubscribe() {
_this6.removeListener(event, listener);
};
if (once) {
this.once(event, listener);
} else {
this.on(event, listener);
}
return unsubscribe;
}
}]);
return AsyncEmitter;
}(_events.EventEmitter);
exports.default = AsyncEmitter;
module.exports = exports['default'];
//# sourceMappingURL=index.js.map