@reactivex/ix-esnext-esm
Version:
The Interactive Extensions for JavaScript
65 lines (63 loc) • 2.15 kB
JavaScript
import { AsyncIterableX } from '../asynciterablex';
import { MaxRefCountList, RefCountList } from '../../iterable/operators/_refcountlist';
import { create } from '../create';
export class MemoizeAsyncBuffer extends AsyncIterableX {
constructor(source, buffer) {
super();
this._error = null;
this._shared = null;
this._stopped = false;
this._source = source;
this._buffer = buffer;
}
[Symbol.asyncIterator]() {
return this._getIterable(0);
}
async *_getIterable(offset = 0) {
let i = offset - 1;
let done = false;
const buffer = this._buffer;
try {
do {
if (++i < buffer.count) {
yield buffer.get(i);
continue;
}
if (this._stopped) {
throw this._error;
}
if (this._shared === null) {
this._shared = this._source.next().then(r => {
this._shared = null;
if (!r.done) {
buffer.push(r.value);
}
return r;
});
}
({ done } = await this._shared.catch(e => {
this._error = e;
this._stopped = true;
throw e;
}));
if (!done) {
yield buffer.get(i);
}
} while (!done);
}
finally {
buffer.done();
}
}
}
export function memoize(readerCount = -1, selector) {
return function memoizeOperatorFunction(source) {
if (!selector) {
return readerCount === -1
? new MemoizeAsyncBuffer(source[Symbol.asyncIterator](), new MaxRefCountList())
: new MemoizeAsyncBuffer(source[Symbol.asyncIterator](), new RefCountList(readerCount));
}
return create(() => selector(memoize(readerCount)(source))[Symbol.asyncIterator]());
};
}
//# sourceMappingURL=memoize.mjs.map