Search code examples
javascriptpromisees6-promise

promise.all on a partial array of promises executes the original array instead


Here's the code (it's a simple test, to see how this works so I can apply it to a larger work project):

async function wait(seconds) {
  return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}

async function printer(seconds) {
  await wait(seconds);
  console.log("Hello");
}

async function main() {
  const list = [];

  for (let i = 0; i < 10; i++) {
    list.push(printer(i));
  }

  list.splice(0, 3);

  await Promise.all(list);
}

main();

Desired behavior: Hello gets printed 7 times
Actual behavior: Hello gets printed 10 times


Solution

  • Rather than invoking each printer function when creating our list of promises, we can create a list of N functions, each with its own delay in seconds (from 1 to 10).

    Once we've created our list of 10 functions, we can splice to drop the required amount, then call each function in turn to create our list of 7 promises.

    Finally we can await the results by calling Promise.all().

    async function wait(seconds) {
      return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
    }
    
    function createPrinter(seconds) {
        return () => printer(seconds);
    }
    
    async function printer(seconds) {
      await wait(seconds)
      console.log("Hello");
    }
    
    async function main() {
      const list = [];
    
      for (let i = 0; i < 10; i++) {
        list.push(createPrinter(i));
      }
    
      list.splice(0, 3);
    
      const promises = list.map(fn => fn());
      await Promise.all(promises);
    }
    
    main();
    .as-console-wrapper { max-height: 100% !important; }