UNPKG

@node-dlc/core

Version:
64 lines (53 loc) 1.76 kB
import { EventEmitter } from 'events'; import { Queue } from './Queue'; /** * Serializes execution of events. This class is constructed with * a delegate function that is executed for each item that is enqueued. */ export class AsyncProcessingQueue<T> extends EventEmitter { private _fn: (...args: T[]) => Promise<void>; // eslint-disable-next-line @typescript-eslint/no-explicit-any private _queue: Queue<any>; // eslint-disable-next-line @typescript-eslint/no-explicit-any private _flushHandle: any; constructor(fn: (...args: T[]) => Promise<void>) { super(); this._fn = fn; this._queue = new Queue(); this._flush = this._flush.bind(this); } /** * Adds a new item to the processing queue */ public enqueue(value: T): void { this._queue.enqueue(value); // Postpone flushing until end of event loop to allow multiple operations // to enqueue. This handle will be cleared once flushing has completed. if (!this._flushHandle) this._flushHandle = setImmediate(this._flush); } /** * Gets the number of pending items in the processor queue * @type {number} */ get size(): number { return this._queue.length; } private async _flush() { // emit that flushing is starting this.emit('flushing'); // process all items on the queue, even items that // are added to the queue while flushing is occuring while (this._queue.length > 0) { try { const value = this._queue.dequeue(); await this._fn(value); } catch (ex) { this.emit('error', ex); } } // emit flushing has completed this.emit('flushed'); // clear flush handle so that next enqueue will trigger a flush this._flushHandle = undefined; } }