Skip to content

Instantly share code, notes, and snippets.

@mridang
Last active October 15, 2024 06:06
Show Gist options
  • Save mridang/758640649f124741e25ff29a561536b4 to your computer and use it in GitHub Desktop.
Save mridang/758640649f124741e25ff29a561536b4 to your computer and use it in GitHub Desktop.
rxjs_fast_paginate

I recently needed a blazing fast concurrent to fetch items from an API. Of course, I could use a combination of async-awaits and some cryptic code with promises and so I took a stab at doing this in rxjs.

import { Observable } from 'rxjs';

export function doPaginate<T>(
  fetchPage: (page: number) => Promise<{ totalRows: number; resultItems: T[] }>,
): Observable<T> {
  return new Observable<T>((subscriber) => {
    // eslint-disable-next-line @typescript-eslint/no-floating-promises
    (async () => {
      try {
        const firstPage = await fetchPage(1);
        const totalPages = Math.ceil(
          firstPage.totalRows / firstPage.resultItems.length,
        );

        firstPage.resultItems.forEach((item) => subscriber.next(item));

        for (let pageNum = 2; pageNum <= totalPages; pageNum++) {
          const { resultItems } = await fetchPage(pageNum);
          resultItems.forEach((item) => subscriber.next(item));
        }

        subscriber.complete();
      } catch (error) {
        subscriber.error(error);
      }
    })(); // Immediately invoked async function expression
  });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment