flow-event
Version:
148 lines (132 loc) • 4.38 kB
JavaScript
function EventEmitter() {
this.ee = new Map();
/** advanced*/
this.queues = new Map(); // Store queue for each event
this.processingStates = new Map(); // Processing state of each event
this.maxConcurrentPerEvent = 10; // Maximum number of concurrent processes for each event
}
// Check if an event exists
EventEmitter.prototype.has = function (name) {
return this.ee.has(name);
};
// Count the number of listeners for an event
EventEmitter.prototype.listenerCount = function (name) {
if (this.ee.has(name)) {
return this.ee.get(name).size;
}
return 0;
};
// Return a list of current events
EventEmitter.prototype.eventNames = function () {
return Array.from(this.ee.keys());
};
// Clear the queue for an event
EventEmitter.prototype.clearQueue = function (name) {
if (this.queues.has(name)) {
this.queues.set(name, []);
return true;
}
return false;
};
// Get the queue for an event
EventEmitter.prototype.getQueue = function (name) {
return this.queues.has(name) ? Array.from(this.queues.get(name)) : [];
};
// Check if an event is processing
EventEmitter.prototype.isProcessing = function (name) {
return this.processingStates.get(name) === true;
};
EventEmitter.prototype.validate = function (name, listener) {
return typeof name === 'string' && typeof listener === 'function';
};
EventEmitter.prototype.addListener = function (name, listener) {
if (this.validate(name, listener)) {
if (!this.ee.has(name)) {
this.ee.set(name, new Map());
}
const id = Symbol(name);
this.ee.get(name).set(id, listener);
return {
id,
remove: () => this.removeId(name, id)
};
}
return { remove: () => null }
};
EventEmitter.prototype.once = function (name, listener) {
if (this.validate(name, listener)) {
const id = Symbol(name);
const onceCallback = (data) => {
listener(data);
this.removeId(name, id);
};
if (!this.ee.has(name)) {
this.ee.set(name, new Map());
}
this.ee.get(name).set(id, onceCallback);
return {
id,
remove: () => this.removeId(name, id)
};
}
};
EventEmitter.prototype.removeId = function (name, id) {
if (this.ee.has(name)) {
return this.ee.get(name).delete(id);
}
return false;
};
EventEmitter.prototype.remove = function (name) {
if (this.ee.has(name)) {
return this.ee.delete(name);
}
return false;
};
EventEmitter.prototype.removeAll = function () {
return this.ee.clear();
};
EventEmitter.prototype.emit = function (name, ...data) {
if (this.ee.has(name)) {
for (const [id, callback] of this.ee.get(name).entries()) {
callback(...data);
}
}
};
EventEmitter.prototype.emitQueue = function (name, ...data) {
// Put the event into the queue of `name`
if (!this.queues.has(name)) {
this.queues.set(name, []);
}
this.queues.get(name).push(data);
// Queue processing
this.processQueue(name);
};
EventEmitter.prototype.processQueue = function () {
// Check if there is a queue or not
if (this.processingStates.get(name) || !this.queues.has(name)) return;
this.processingStates.set(name, true); // Set status to processing
const queue = this.queues.get(name);
let currentBatch = 0;
const processBatch = () => {
while (currentBatch < this.maxConcurrentPerEvent && queue.length > 0) {
const data = queue.shift(); // Get data from queue
if (this.ee.has(name)) {
for (const [id, callback] of this.ee.get(name).entries()) {
callback(...data); // Call callback for event
}
}
currentBatch++;
}
if (queue.length > 0) {
currentBatch = 0;
setTimeout(processBatch, 100); // Pause before processing next batch
} else {
this.processingStates.set(name, false); //Set status to not processing
}
};
processBatch();
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.off = EventEmitter.prototype.remove;
EventEmitter.prototype.removeAllListeners = EventEmitter.prototype.removeAll;
export default EventEmitter