Javascript push a promise into an array

it seems they are being called instead of inserted and wait for Promise.all()

It seems like you want the code inside the promises to simultaneously run when you call Promise.all.

If that is what you want then wrapping code in the promises is probably not what you want.


Instead you need to wrap the code you want to run later in just a plain ole function. You can add those functions to an array and then call each one in a loop. And by the looks of your code, you probably don't even need to promises.

See the example below:

// this function returns another function `runnable` and can be called later (synchronously) to get the result
function runLater (index) {
  return function runnable() {
    console.log(`this code is ran later. from ${index}`);
    return `from ${index}`;
  }
}

console.log('this is run now');

const tasks = [];

for (let i = 0; i < 3; i += 1) {
  tasks.push(runLater(i));
}

console.log('this is run');


// use Array.prototype.map to map the array of functions to what they return by invoking each one.
const valuesOfTasks = tasks.map(task => task());
console.log({valuesOfTasks});

console.log('this is run after');


You only need promises when you're dealing with async control flow. Delaying execution can be done synchronously, just by wrapping a section of code in a function. When you want to execute that code, just invoke the function.

Edit:

I need to wait for all the useSpecialAbility to be done before moving on with my code. Some of them will write/read from the database, that's why I used promises.

In that case you will have to use Promise.all but you'll still need to wrap those promises in functions with no arguments if you want them to all run at the same time.


The code block of promises is actually ran synchronously (vs running the block when you call .then or Promise.all) so if you still want the promises run later, you can still just wrap them in functions.

See this example:

function waitThenSay(milliseconds, message) {
  return new Promise(resolve => {
    console.log(`waiting to say: "${message}"...`)
    setTimeout(() => {
      // log to console for immediate side-effect
      console.log(message.toUpperCase() + '!');
      // also resolve with the message
      resolve(message);
    }, milliseconds);
  });
}

console.log('this is run first');

// tasks is an array of functions that return promises
const tasks = [];
for (let i = 1; i <= 3; i += 1) {
  tasks.push(() => waitThenSay(i * 2000, `hello from task ${i}`));
}

console.log('this is run second');

// execute the tasks by mapping each function to their invocation
const arrayOfPromises = tasks.map(task => task())

// call Promise.all on that array
Promise.all(arrayOfPromises).then(result => {
  console.log({result});
});

Hope this helps!