chunk<T>() and chunkAsync<T>() batch iterables
TypeScript
/** Lazily split any iterable into arrays of at most `size` items. */
export function* chunk<T>(items: Iterable<T>, size: number): Generator<T[], void, void> {
if (!Number.isInteger(size) || size < 1) throw new RangeError(`size must be a positive integer, got ${size}`);
let batch: T[] = [];
for (const item of items) {
batch.push(item);
if (batch.length === size) {
yield batch;
batch = [];
}
}
if (batch.length > 0) yield batch;
}
/** Batch an async source such as a paginated API stream. */
export async function* chunkAsync<T>(items: AsyncIterable<T>, size: number): AsyncGenerator<T[], void, void> {
if (!Number.isInteger(size) || size < 1) throw new RangeError(`size must be a positive integer, got ${size}`);
let batch: T[] = [];
for await (const item of items) {
batch.push(item);
if (batch.length === size) {
yield batch;
batch = [];
}
}
if (batch.length > 0) yield batch;
}
// for (const page of chunk(ids, 100)) await api.fetchMany(page);