Search code examples
javascriptpromisenodes

JS: what's the different in Promise.all


I just wonder if there is different between those 2 calls by await Promise.all([/* ... /*]) In my performance test, it took the same time.

This is my method to be invoked by the Promise.all:

const makeFetch1 = async () => {
  axios.get("https://jsonplaceholder.typicode.com/todos/1");
};

const makeFetch2 = async () => {
  return axios.get("https://jsonplaceholder.typicode.com/todos/1");
};

1) await Promise.all([makeFetch1(), makeFetch1(), ...])
2) await Promise.all([makeFetch2(), makeFetch2(), ...])

Both have the same execution time result, what i should choose?


Solution

  • There are several major differences and multiple coding mistakes.

    First off this code:

    const makeFetch1 = async () => {
      axios.get("https://jsonplaceholder.typicode.com/todos/1");
    };
    

    is an async function that calls axios.get() and then immediately returns a promise that is already resolved and has an undefined resolved value. Nothing here waits for the axios.get() call to finish.

    Your second code block:

    const makeFetch2 = async () => {
      return axios.get("https://jsonplaceholder.typicode.com/todos/1");
    };
    

    calls axios.get() and returns the promise that it creates. So, the promise this function returns will be tied to when the axios.get() call completes and the resolved value will be the resolved value of the axios call.

    Differences:

    1. You could use the makeFetch2() function to get the result of the axios.get() call (resolved value or reject error). You could not use makeFetch1() to get the result of the axios.get() call because that result is not communicated back to the caller in any way.

    2. Similarly, makeFetch2() will allow the caller to know when the axios operation has completed. makeFetch1() will not.

    3. If the axios.get() operation rejected, then makeFetch1() would result in an unhandled rejection error because nothing is listening for the rejection.

    Then, these two:

    await Promise.all([makeFetch1, makeFetch1, ...])
    await Promise.all([makeFetch2, makeFetch2, ...])
    

    Are both pretty useless because you're not calling any of the functions so nothing is executing. These will both just resolve immediately with a resolved value of an array of function references. None of the axios calls are executed because nothing actually calls makeFetch1() or makeFetch2().


    If you meant to actually execute the functions with these two:

    await Promise.all([makeFetch1(), makeFetch1(), ...])
    await Promise.all([makeFetch2(), makeFetch2(), ...])
    

    Then, the first one just resolves immediately with an array of undefined values as the resolved value because remember the makeFetch1() return value isn't connected in any way to the axios.get() call.

    The second one will properly wait for all the axios.get() calls in makeFetch2() to complete and will resolve with an array of values from the axios.get() calls.


    Both have the same execution time result, what i should choose?

    That's because as you've implemented them, you aren't calling the makeFetchN() functions in either case. So, they aren't doing anything and thus have the same execution time.

    If you change the implementation to actually call the functions as in:

    await Promise.all([makeFetch1(), makeFetch1(), ...])
    await Promise.all([makeFetch2(), makeFetch2(), ...])
    

    There will be a significant timing difference because the one based on makeFetch1() does not wait for any of the axios.get() calls to finish and does not communicate back results or completion and is subject to uncaught rejections.

    The one based on makeFetch1() has no practical use as you could just do:

    makeFetch1();
    makeFetch1();
    ...
    

    with the exact same result because makeFetch1() just returns an immediately resolved promise so passing them all to Promise.all() isn't doing anything useful.

    makeFetch1() is probably just not useful since it doesn't inform the caller of completion, error or resolved value.