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).
128 lines (127 loc) • 4.76 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var deferred_1 = require("./deferred");
/**
* The async iterator equivalent of a deferred
*/
var Subject = /** @class */ (function () {
function Subject() {
var _a;
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;
var self = this;
this.iterator = (_a = {
throw: function (e) {
self.done = true;
self.finallyCallbacks.map(function (cb) { return cb(); });
// fail any waiting deferreds
for (var _i = 0, _a = self.deferreds; _i < _a.length; _i++) {
var deferred = _a[_i];
deferred.reject(e);
}
return Promise.reject(e);
},
return: function (value) {
self.done = true;
self.finallyCallbacks.map(function (cb) { return cb(); });
// fail any waiting deferreds
for (var _i = 0, _a = self.deferreds; _i < _a.length; _i++) {
var deferred = _a[_i];
deferred.resolve({
done: true,
value: {}
});
}
return Promise.resolve(self.doneValue);
},
next: function (value) {
if (self.error) {
return Promise.reject(self.error);
}
var 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(function (cb) { return cb(); });
}
if (self.done) {
return Promise.resolve({
done: true,
value: {}
});
}
var deferred = new deferred_1.Deferred();
self.deferreds.push(deferred);
return deferred.promise;
}
}
},
_a[Symbol.asyncIterator] = function () {
return this;
},
_a);
}
Subject.prototype.finally = function (callback) {
this.finallyCallbacks.push(callback);
};
Subject.prototype.onCompleted = function () {
return this.callback({ done: true, value: {} });
};
Subject.prototype.onNext = function (value) {
return this.callback({ done: false, value: value });
};
Subject.prototype.onError = function (error) {
this.error = error;
for (var _i = 0, _a = this.deferreds; _i < _a.length; _i++) {
var queuedDeferred = _a[_i];
queuedDeferred.reject(error);
}
this.noMoreResults = true;
};
Subject.prototype.isDone = function () {
return this.done;
};
Subject.prototype.callback = function (result) {
if (!(this && this instanceof Subject)) {
var 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 (var _i = 0, _a = this.deferreds; _i < _a.length; _i++) {
var queuedDeferred = _a[_i];
queuedDeferred.resolve(result);
}
this.noMoreResults = true;
return Promise.resolve();
}
var deferred = this.deferreds.pop();
if (deferred !== undefined) {
deferred.resolve(result);
return Promise.resolve();
}
else {
this.queue.push(result);
return this.backPressureDeferred.promise;
}
};
return Subject;
}());
exports.Subject = Subject;