UNPKG

web-worker-helper

Version:

Utilities for running tasks on worker threads

88 lines (87 loc) 3.19 kB
// From https://github.com/rauschma/async-iter-demo/tree/master/src under MIT license // http://2ality.com/2016/10/asynchronous-iteration.html /** * Async Queue * - AsyncIterable: An async iterator can be * - Values can be pushed onto the queue * @example * const asyncQueue = new AsyncQueue(); * setTimeout(() => asyncQueue.enqueue('tick'), 1000); * setTimeout(() => asyncQueue.enqueue(new Error('done')), 10000); * for await (const value of asyncQueue) { * console.log(value); // tick * } */ var AsyncQueue = /** @class */ (function () { function AsyncQueue() { this._values = []; // enqueues > dequeues this._settlers = []; // dequeues > enqueues this._closed = false; } /** Return an async iterator for this queue */ AsyncQueue.prototype[Symbol.asyncIterator] = function () { return this; }; /** Push a new value - the async iterator will yield a promise resolved to this value */ AsyncQueue.prototype.push = function (value) { return this.enqueue(value); }; /** * Push a new value - the async iterator will yield a promise resolved to this value * Add an error - the async iterator will yield a promise rejected with this value */ AsyncQueue.prototype.enqueue = function (value) { if (this._closed) { throw new Error('Closed'); } if (this._settlers.length > 0) { if (this._values.length > 0) { throw new Error('Illegal internal state'); } var settler = this._settlers.shift(); if (value instanceof Error) { settler.reject(value); } else { settler.resolve({ value: value }); } } else { this._values.push(value); } }; /** Indicate that we not waiting for more values - The async iterator will be done */ AsyncQueue.prototype.close = function () { while (this._settlers.length > 0) { var settler = this._settlers.shift(); settler.resolve({ done: true }); } this._closed = true; }; // ITERATOR IMPLEMENTATION /** @returns a Promise for an IteratorResult */ AsyncQueue.prototype.next = function () { var _this = this; // If values in queue, yield the first value if (this._values.length > 0) { var value = this._values.shift(); if (value instanceof Error) { return Promise.reject(value); } return Promise.resolve({ done: false, value: value }); } // If queue is closed, the iterator is done if (this._closed) { if (this._settlers.length > 0) { throw new Error('Illegal internal state'); } return Promise.resolve({ done: true, value: undefined }); } // Yield a promise that waits for new values to be enqueued return new Promise(function (resolve, reject) { _this._settlers.push({ resolve: resolve, reject: reject }); }); }; return AsyncQueue; }()); export default AsyncQueue;