@codibre/fluent-iterable
Version:
Provides LINQ-like fluent api operations for iterables and async iterables (ES2018+).
34 lines (33 loc) • 1.43 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeIterators = mergeIterators;
exports.mergeIterables = mergeIterables;
const get_next_async_iterator_factory_1 = require("./get-next-async-iterator-factory");
async function getNextValue(asyncIteratorsValues) {
return Promise.race(Array.from(asyncIteratorsValues.values()));
}
async function* mergeIterators(callback, ...iterators) {
const getNextAsyncIteratorValue = (0, get_next_async_iterator_factory_1.getNextAsyncIteratorFactory)(callback);
const asyncIteratorsValues = new Map();
iterators.forEach((it, idx) => asyncIteratorsValues.set(idx, getNextAsyncIteratorValue(it, idx)));
while (asyncIteratorsValues.size > 0) {
const { result, index } = await getNextValue(asyncIteratorsValues);
if (result.done) {
if (iterators[index].return) {
iterators[index].return();
}
asyncIteratorsValues.delete(index);
}
else {
yield result.value;
asyncIteratorsValues.set(index, getNextAsyncIteratorValue(iterators[index], index));
}
}
}
function mergeIterables(callback, ...iterables) {
if (callback && typeof callback !== 'function') {
iterables = [callback, ...iterables];
callback = undefined;
}
return mergeIterators(callback, ...iterables.map((x) => x[Symbol.asyncIterator]()));
}