Batch Items From Async Iterables

Group values from async iterables into fixed-size arrays, yielding full batches and a final partial batch without buffering all.

TypescriptData Fetching

Code

snippet
export async function* batchAsync<T>(
  source: AsyncIterable<T> | Iterable<T>,
  size: number,
): AsyncGenerator<T[], void, void> {
  if (!Number.isInteger(size) || size < 1) {
    throw new RangeError("size must be a positive integer");
  }
  if (source === null || source === undefined) {
    throw new TypeError("source must be iterable");
  }
  let batch: T[] = [];
  for await (const item of source) {
    batch.push(item);
    if (batch.length === size) {
      yield batch;
      batch = [];
    }
  }
  if (batch.length > 0) yield batch;
}

export async function collectBatches<T>(
  source: AsyncIterable<T> | Iterable<T>,
  size: number,
): Promise<T[][]> {
  const output: T[][] = [];
  for await (const batch of batchAsync(source, size)) output.push(batch);
  return output;
}