Search code examples
javascriptnode.jses6-promise

How can I modify the array passed to Promise.all


My node.js class is recursively loading files from the file system asynchronously.

Other methods of my class are not valid until all of the files have finished loading, so I defined an array of promises, and do Promise.all() on the array before executing methods that depend on the loading being complete.

As the code discovers each file or directory, it adds a new promise to the array so that the array eventually contains one promise for each directory scanned and each file loaded. I have verified that this is working as designed.

The problem is that Promise.all() seems to only wait on promises that are already in the array when it is called, and does not wait for promises that are added to the array after Promise.all() is called, so the promise returned by Promise.all() is resolved before all of the files have been loaded.

Yes, I did make sure that new promises are added to the array before the current promise is resolved to avoid that race condition.

Assuming that I can't use Promise.all() in this situation, what is the best alternative?


Solution

  • Thank you for the link to How to know when all Promises are Resolved in a dynamic "iterable" parameter?. Using info from this thread I was able to come up with a working solution as follows:

      private readonly loadingPromises: Promise<any>[];
    
      private async finishLoading(): Promise<void> {
        var completedCount = 0;
        while (this.loadingPromises.length != completedCount) {
          var waitCount = this.loadingPromises.length;
          await Promise.all(this.loadingPromises);
          completedCount = waitCount;
        }
        this.loadingPromises.length = 0;
      }
    
      async somePublicMethod() {
        return this.finishLoading().then(() => {
          //... do stuff here
        });
      }