asyncplify
Version:
FRP (functional reactive programming) library for Javascript
58 lines (49 loc) • 1.8 kB
JavaScript
Asyncplify.merge = function (options) {
return new Asyncplify(Merge, options);
};
function Merge(options, sink) {
this.concurrency = 0;
this.index = 0;
this.items = options.items || options || [];
this.maxConcurrency = options.maxConcurrency || 0;
this.sink = sink;
this.sink.source = this;
this.subscriptions = [];
while (this.index < this.items.length && (this.maxConcurrency < 1 || this.concurrency < this.maxConcurrency))
new MergeItem(this.items[this.index++], this);
if (!this.items.length) this.sink.end(null);
}
Merge.prototype.setState = function (state) {
for (var i = 0; i < this.subscriptions.length; i++)
this.subscriptions[i].setState(state);
this.subscriptions.length = 0;
};
function MergeItem(item, parent) {
this.parent = parent;
this.source = null;
parent.concurrency++;
parent.subscriptions.push(this);
item._subscribe(this);
}
MergeItem.prototype = {
emit: function (v) {
this.parent.sink.emit(v);
},
end: function (err) {
if (this.source) {
this.source = null;
this.parent.concurrency--;
removeItem(this.parent.subscriptions, this);
if (err || this.parent.index >= this.parent.items.length) {
var sink = this.parent.sink;
this.parent.setState(Asyncplify.states.CLOSED);
sink.end(err);
} else if (this.parent.maxConcurrency < 1 || this.parent.concurrency < this.parent.maxConcurrency) {
new MergeItem(this.parent.items[this.parent.index++], this.parent);
}
}
},
setState: function (state) {
if (this.source) this.source.setState(state);
}
};