Repository: mozilla/pdf.js
File: src/core/document.js (JavaScript)

Code before:
              xref: this.xref,
              pageIndex,
              pageDict,
              ref,
              globalIdFactory: this._globalIdFactory,
              fontCache: catalog.fontCache,
              builtInCMapCache: catalog.builtInCMapCache,
              standardFontDataCache: catalog.standardFontDataCache,
              globalImageCache: catalog.globalImageCache,
              systemFontCache: catalog.systemFontCache,
              nonBlendModesSet: catalog.nonBlendModesSet,
              xfaFactory: null,
            })
          );
        }

        this._pagePromises.set(pageIndex, promise);
      }
      catalog.setActualNumPages(pagesTree.size);
    }
  }

  fontFallback(id, handler) {
    return this.catalog.fontFallback(id, handler);
  }

  async cleanup(manuallyTriggered = false) {
    return this.catalog
      ? this.catalog.cleanup(manuallyTriggered)
      : clearGlobalCaches();
  }

  async #collectFieldObjects(
    name,
    parentRef,
    fieldRef,
    promises,
    annotationGlobals,
    visitedRefs,
    orphanFields
  ) {
    const { xref } = this;

    if (!(fieldRef instanceof Ref) || visitedRefs.has(fieldRef)) {
      return;
    }
    visitedRefs.put(fieldRef);
    const field = await xref.fetchAsync(fieldRef);
    if (!(field instanceof Dict)) {
      return;
    }

Review comment (suggestion):
While reading this code I was wondering if it'd be possible to just iterate on the promises every time one is resolved instead of awaiting on all of them.
I didn't manage to find something on MDN but I wrote a small piece of code (untested) to try to achieve that:
```js
class Foo {
  #current = Promise.withResolvers();

  #count;

  constructor(promises) {
    this.#count = promises.length;
    for (const promise of promises) {
      promise.then(result => {
        this.#count--;
        this.#current.resolve(result);
      });
    }
  }

  async *nextPromise() {
    if (this.#count === 0) {
      return;
    }
    const promise = this.#current.promise;
    this.#current = Promise.withResolvers();
    yield promise;
  }
}
```
which can be used with something like:
```js
const x = new Foo(p1, p2, p3, ...);
for await (const r of x.nextPromise()) {
...
}
```

Anyway it's just an untested idea and maybe I'm overthinking that stuff: feel free to forget :)

Code after:
              xref: this.xref,
              pageIndex,
              pageDict,
              ref,
              globalIdFactory: this._globalIdFactory,
              fontCache: catalog.fontCache,
              builtInCMapCache: catalog.builtInCMapCache,
              standardFontDataCache: catalog.standardFontDataCache,
              globalImageCache: catalog.globalImageCache,
              systemFontCache: catalog.systemFontCache,
              nonBlendModesSet: catalog.nonBlendModesSet,
              xfaFactory: null,
            })
          );
        }

        this._pagePromises.set(pageIndex, promise);
      }
      catalog.setActualNumPages(pagesTree.size);
    }
  }

  async fontFallback(id, handler) {
    const { catalog, pdfManager } = this;

    for (const translatedFont of await Promise.all(catalog.fontCache)) {
      if (translatedFont.loadedName === id) {
        translatedFont.fallback(handler, pdfManager.evaluatorOptions);
        return;
      }
    }
  }

  async cleanup(manuallyTriggered = false) {
    return this.catalog
      ? this.catalog.cleanup(manuallyTriggered)
      : clearGlobalCaches();
  }

  async #collectFieldObjects(
    name,
    parentRef,
    fieldRef,
    promises,
    annotationGlobals,
    visitedRefs,
    orphanFields
  ) {
    const { xref } = this;

    if (!(fieldRef instanceof Ref) || visitedRefs.has(fieldRef)) {