@lyra/form-builder
Version:
Lyra form builder
62 lines (51 loc) • 1.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.withMaxConcurrency = withMaxConcurrency;
exports.createThrottler = createThrottler;
var _rxjs = require('rxjs');
const DEFAULT_CONCURRENCY = 4;
// Takes a observable-returning function and returns a new function that limits on the number of
// concurrent observables.
function remove /*:: <T>*/(array /*: Array<T>*/, item /*: T*/) /*: Array<T>*/ {
const index = array.indexOf(item);
if (index > -1) {
array.splice(index, 1);
}
return array;
}
function withMaxConcurrency(func /*: any => Observable<*>*/, concurrency /*: number*/ = DEFAULT_CONCURRENCY) {
const throttler = createThrottler(concurrency);
return (...args /*: Array<any>*/) => (0, _rxjs.from)(throttler(func(...args)));
}
function createThrottler(concurrency /*: number*/ = DEFAULT_CONCURRENCY) {
const currentSubscriptions /*: Array<Subscription>*/ = [];
const pendingObservables /*: Array<Observable<*>>*/ = [];
const ready$ = new _rxjs.Subject();
return request;
function request(observable /*: Observable<*>*/) {
return new _rxjs.Observable(observer => {
if (currentSubscriptions.length >= concurrency) {
return scheduleAndWait(observable).mergeMap(request).subscribe(observer);
}
const subscription = observable.subscribe(observer);
currentSubscriptions.push(subscription);
return () => {
remove(currentSubscriptions, subscription);
remove(pendingObservables, observable);
subscription.unsubscribe();
check();
};
});
}
function scheduleAndWait(observable) {
pendingObservables.push(observable);
return ready$.asObservable().first(obs => obs === observable);
}
function check() {
while (pendingObservables.length > 0 && currentSubscriptions.length < concurrency) {
ready$.next(pendingObservables.shift());
}
}
}