thatguy
thatguy

Reputation: 410

Understanding Promise.all and Array.map()

I am retrieving data from multiple API's and these data will be aggregated into a final array where I intend to map through and display in the UI (using React). So for better context, I have this kind of scenario.

First I retrieve the major data from the main API

const response = await getFirstData() // returns an array

const [secondResult, thirdResult, fourthResult] = await Promise.all([
 response.map(async (item) => await secondApiRequest()),
 response.map(async (item) => await thirdApiRequest()),
 response.map(async (item) => await fourthApiRequest())
])

As you can see from above, based on the response from the main API, I then map through the array returned to get data from other APIs (secondApiRequest(), etc..). Now I was thinking that secondResult, thirdResult, fourthResult would resolve to an array of objects as it should be. But when I check the logs on chrome browser I see this instead.

0: Promise {<fulfilled>: Array(10)}
1: Promise {<fulfilled>: Array(10)}
2: Promise {<fulfilled>: Array(10)}
3: Promise {<fulfilled>: Array(10)}
4: Promise {<fulfilled>: Array(10)}
5: Promise {<fulfilled>: Array(5)}
6: Promise {<fulfilled>: Array(0)}
7: Promise {<fulfilled>: Array(0)}
8: Promise {<fulfilled>: Array(0)}
9: Promise {<fulfilled>: Array(0)}

I understand that these operations are run in parallel, but how do I get these operations to resolve and return the final arrays that should contain objects. Also, what would be the most efficient way to achieve this because the finalArray will contain more than 200 objects at the end and I have to display that on the UI. Thank you, any help is welcome.

Upvotes: 2

Views: 2571

Answers (2)

Ori Drori
Ori Drori

Reputation: 191996

If you want to make all requests in parallel, you should return an array of promises to Promise.all().

Map response for each api, and wait for it's array of promises with Promise.all(), then await all internal Promise.all() calls with an external one.

const response = await getFirstData() // returns an array

const [secondResult, thirdResult, fourthResult] = await Promise.all(
  [secondApiRequest, thirdApiRequest, fourthApiRequest]
    .map(api => Promise.all(response.map(api)))
)

Upvotes: 3

Guerric P
Guerric P

Reputation: 31815

This allows you to run the subsequent requests in parallel and retrieve their results in the corresponding variables:

const response = await getFirstData(); // returns an array

const [secondResult, thirdResult, fourthResult] = await Promise.all([
  Promise.all(response.map(item => secondApiRequest()),
  Promise.all(response.map(item => thirdApiRequest()),
  Promise.all(response.map(item => fourthApiRequest())
]);

Upvotes: 0

Related Questions