Skip to content
GreenSnippets

Fetch every page of a paginated API with an async generator

Iterate cursor-paginated API results with for await, loading pages lazily and stopping early when needed.

JavaScript
async function* paginate(fetchPage, { maxPages = 1000 } = {}) {
  let cursor;
  for (let page = 0; page < maxPages; page++) {
    const { items, next_cursor: next } = await fetchPage(cursor);
    yield* items;
    if (!next) return;
    cursor = next;
  }
  throw new Error(`Pagination exceeded ${maxPages} pages`);
}

Example / expected output

Output
for await (const user of paginate((cursor) => api.listUsers({ cursor }))) {
  console.log(user.id);
}

How it works

An async generator hides the pagination loop: callers just for await over items. Pages load lazily, so breaking out of the loop stops further requests. This version follows a next_cursor field; adapt the property names to your API (some use Link headers or page numbers).

Add a hard page cap so a buggy server that never ends pagination cannot loop forever.