web-worker-helper
Version:
Utilities for running tasks on worker threads
90 lines (89 loc) • 3.27 kB
JavaScript
;
// From https://github.com/rauschma/async-iter-demo/tree/master/src under MIT license
// http://2ality.com/2016/10/asynchronous-iteration.html
Object.defineProperty(exports, "__esModule", { value: true });
/**
* 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;
}());
exports.default = AsyncQueue;