UNPKG

axax

Version:

A library of async iterator extensions for JavaScript including ```map```, ```reduce```, ```filter```, ```flatMap```, ```pipe``` and [more](https://github.com/jamiemccrindle/axax/blob/master/docs/API.md#functions).

121 lines (120 loc) 3.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const deferred_1 = require("./deferred"); /** * The async iterator equivalent of a deferred */ class Subject { constructor() { this.doneValue = { done: true, value: {} }; this.queue = []; this.deferreds = []; this.done = false; this.noMoreResults = false; this.backPressureDeferred = new deferred_1.Deferred(); this.finallyCallbacks = []; this.error = undefined; const self = this; this.iterator = { throw(e) { self.done = true; self.finallyCallbacks.map(cb => cb()); // fail any waiting deferreds for (const deferred of self.deferreds) { deferred.reject(e); } return Promise.reject(e); }, return(value) { self.done = true; self.finallyCallbacks.map(cb => cb()); // fail any waiting deferreds for (const deferred of self.deferreds) { deferred.resolve({ done: true, value: {} }); } return Promise.resolve(self.doneValue); }, next(value) { if (self.error) { return Promise.reject(self.error); } const queuedItem = self.queue.shift(); if (self.queue.length === 0) { self.backPressureDeferred.resolve(); self.backPressureDeferred = new deferred_1.Deferred(); } if (queuedItem !== undefined) { return Promise.resolve(queuedItem); } else { if (self.noMoreResults && !self.done) { self.done = true; self.finallyCallbacks.map(cb => cb()); } if (self.done) { return Promise.resolve({ done: true, value: {} }); } const deferred = new deferred_1.Deferred(); self.deferreds.push(deferred); return deferred.promise; } }, [Symbol.asyncIterator]() { return this; } }; } finally(callback) { this.finallyCallbacks.push(callback); } onCompleted() { return this.callback({ done: true, value: {} }); } onNext(value) { return this.callback({ done: false, value }); } onError(error) { this.error = error; for (const queuedDeferred of this.deferreds) { queuedDeferred.reject(error); } this.noMoreResults = true; } isDone() { return this.done; } callback(result) { if (!(this && this instanceof Subject)) { const errorMessage = "This must be a Subject. Have you bound this?"; // tslint:disable-next-line:no-console console.log(errorMessage); throw new Error(errorMessage); } if (result.done) { for (const queuedDeferred of this.deferreds) { queuedDeferred.resolve(result); } this.noMoreResults = true; return Promise.resolve(); } const deferred = this.deferreds.pop(); if (deferred !== undefined) { deferred.resolve(result); return Promise.resolve(); } else { this.queue.push(result); return this.backPressureDeferred.promise; } } } exports.Subject = Subject;