-3

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?

Ballon Ura
  • 882
  • 1
  • 13
  • 36
  • 1
    Note that the first arrow function doesn't return anything beyond the async wrapper promise. Only single-statement arrow functions return data, the moment you have a function body inside curly brackets you need a `return` keyword. – Mike 'Pomax' Kamermans Jan 05 '22 at 17:38
  • 1
    if you don't `return` anything in an async function, it returns a promise with an `undefined` value. – Redu Jan 05 '22 at 17:40
  • 1
    There's no point in using `Promise.all()` with the first one because it's not monitoring any promises at all. It will just resolve immediately while the `fetch()` operations continuing running and eventually finish. The second one tracks both promises and resolves when they both resolve and also resolves with their values. – jfriend00 Jan 05 '22 at 17:50
  • 3
    i would add that `[makeFetch1, ...]`, `[makeFetch2, ...]` does not **call** the `makeFetch*` function. you need to write `Promise.all([makeFetch2(), ...])` – Mulan Jan 05 '22 at 18:14
  • if you are asking what is the performance difference between `(...) => { ... }` and `(...) => ...` go measure it. stackoverflow is not for this kind of question. – Mulan Jan 05 '22 at 18:16

2 Answers2

2

The first one will fire of a request and not return it. so makeFetch1() will result in a Promise that resolves immediately. This is almost certainly never what you want. An async function should await or return inside somewhere, otherwise it may as well be a standard function (that returns nothing).

Even if you don't care about what the request resolves to, you should still use the result of the request (by returning or awaiting, just so you can see if the request succeeds or not - and communicate to the user that there was a problem if it fails)

The second one will fire of a request and return it. so makeFetch1() will result in a Promise that resolves once the request resolves - which is likely to take a number of milliseconds.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

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.

jfriend00
  • 683,504
  • 96
  • 985
  • 979