2

Hello I am trying to run the same function asynchronously using different parameters but cannot figure out how to store the functions without running them before the promise all.

Here's a simplified example of what I am trying to do:

const myFunc = async(paramsAsArray) => {
    // does stuff
}

let paramArray = [ [a,b], [c, d], [e, f] ]
let funcArray = []

for (let i = 0; i < paramArray.length; i++) {

    funcArray.push(myFunc(paramArray[i]))

}

const response = await Promise.all(funcArray)

My functions keep running in the for loop before I can use the promise.all(). Does anyone know what I can do to make them run a using a promise all? Any help or suggestions is appreciated, thanks!

Prox Ima
  • 31
  • 2
  • `Promise.all` takes an array of promises, not an array of functions. Your code works as desired, the only weird thing is the variable name `funcArray` which should be `promiseArray`. What output/behaviour do you expect that you are not getting? – Bergi Mar 24 '23 at 00:24

2 Answers2

3

Wrap your function in another function so it doesn't get called immediately. then call it inside Promise.all

funcArray.push(() => myFunc(paramArray[i]))

const response = await Promise.all(funcArray.map(f=> f()))
user1738539
  • 874
  • 2
  • 11
  • 23
  • This makes no sense. Now you're running *two* loops before the `Promise.all` call, the code still does the same (except with more overhead) – Bergi Mar 24 '23 at 00:25
  • It doesn't do the same thing. If you try OPs example it will start running all `myFunc` before `const response = await Promise.all(funcArray)`. The expectation is that it shouldn't start running those async calls until `Promise.all` is called. I'm sure that there's probably a better way than iterating over the array an extra time but it works – user1738539 Mar 28 '23 at 16:23
  • What do you mean by "before"? `Promise.all` is not magic, it's just a function call. There is no difference between `const response = await Promise.all(funcArray.map(f=>f()));` and `const promises = funcArray.map(f=>f()); const response = await Promise.all(promises);` – Bergi Mar 28 '23 at 19:35
  • The code as written by OP will invoke his `myFunc` as soon as this line is reached `funcArray.push(myFunc(paramArray[i]))` for each of his parameters. The intention is to not run any of those until the `Promise.all` is called as stated by the original question and description – user1738539 Mar 28 '23 at 20:38
  • "Lines" are not what defines "before". If you wanted, you could put all the code on one line, it would still be executed in a certain sequence. And the functions are **always** called before `Promise.all` is called. – Bergi Mar 28 '23 at 20:46
  • When you say "*It doesn't do the same thing.*", can you give some example input that would lead to a different output? – Bergi Mar 28 '23 at 20:47
  • Here I have OPs code and mine. They are not the same https://stackblitz.com/edit/node-rzx3kr – user1738539 Mar 28 '23 at 20:56
  • There is no `console.log('preparing')` in the OP's code in the question nor in your code in your answer. – Bergi Mar 28 '23 at 20:59
  • Just showing the difference with console outputs. Did you even run them? – user1738539 Mar 28 '23 at 21:05
  • I did run them. But that's not the code from your answer or the code from the question, which does not print anything in that loop. – Bergi Mar 28 '23 at 21:25
  • Just write it [like this](https://stackblitz.com/edit/node-gzindm?file=index2.js) and it's the same again, btw – Bergi Mar 28 '23 at 21:28
-1

myFunc(paramArray[i]) calls the function immediately. You are calling it, so you are not pushing the function itself to the array, but its returned value. Also, the Promise resolution starts immediately, not in the Promise.all.

To push the function itself without calling it, and still passing it parmameters, use .bind :

funcArray.push(myFunc.bind(this, paramArray[i]))

You can also build your array using .map() :

const funcArray = paramArray.map( params => myFunc.bind(this, params));
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
  • 1
    trying this retuned the following from the `promise.all()` : "[Function: bound searchMainnetDuoArb] AsyncFunction" and I don't believe it actually ran the function – Prox Ima Feb 23 '22 at 15:38