prex-es5
Version:
Async coordination primitives and extensions on top of ES6 Promises
115 lines (113 loc) • 4.75 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
};
import "./asyncIterable";
import { AsyncQueue } from "./queue";
import { isIterable, isMissing } from "./utils";
const BOUNDARY = Symbol();
/**
* An asynchronous queue with a bounded endpoint.
*/
export class AsyncBoundedQueue {
/**
* Initializes a new instance of the AsyncProducerConsumerQueue class.
*
* @param iterable An optional iterable of values or promises.
*/
constructor(iterable) {
this._queue = new AsyncQueue();
this._state = "open";
if (!isMissing(iterable) && !isIterable(iterable))
throw new TypeError("Object not iterable: iterable.");
if (isIterable(iterable)) {
for (const value of iterable) {
this.put(value);
}
}
}
/**
* Gets the number of entries in the queue.
* When positive, indicates the number of entries available to get.
* When negative, indicates the number of requests waiting to be fulfilled.
*/
get size() {
return this._state === "closing" ? this._queue.size - 1 : this._queue.size;
}
/**
* Adds a value to the end of the queue. If the queue is empty but has a pending
* dequeue request, the value will be dequeued and the request fulfilled.
*
* @param value A value or promise to add to the queue.
*/
put(value) {
if (this._state !== "open")
throw new Error("AsyncProducer is done producing values.");
this._queue.put(value);
}
/**
* Indicates the queue is done adding and that no more items will be added to the queue.
*/
end() {
if (this._state !== "open")
return;
this._state = "closing";
this._queue.put(BOUNDARY);
}
/**
* Removes and returns a Promise for the first value in the queue. If the queue has
* ended, returns a Promise for `undefined`. If the queue is empty, returns a Promise
* for the next value to be added to the queue.
*/
get() {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this._dequeue();
return result === BOUNDARY ? undefined : result;
});
}
/**
* Consumes all items in the queue until the queue ends.
*/
drain() {
return __asyncGenerator(this, arguments, function* drain_1() {
let value = yield __await(this._dequeue());
while (value !== BOUNDARY) {
yield yield __await(value);
value = yield __await(this._dequeue());
}
});
}
_dequeue() {
return __awaiter(this, void 0, void 0, function* () {
if (this._state === "closed")
return BOUNDARY;
let result = BOUNDARY;
try {
result = yield this._queue.get();
}
finally {
if (result === BOUNDARY) {
this._state = "closed";
}
}
return result;
});
}
}
//# sourceMappingURL=boundedQueue.js.map