user13088390
user13088390

Reputation:

How to wait for multiple nested promises to resolve?

I am attempting to make several http requests (using axios), one to each url in a list. As soon as an individual request resolves, I want to make another request to a url constructed from the previous request's response. Finally, when all secondary requests are resolved, I want to do something with all of their responses.

I have attempted to accomplish this as follows:

let promises = [];

urls.forEach(url => {
  const promise = axios.get(url);

  promise.then(response => {
    promises.push(axios.get(response.data.url))
  });
});

Promise.all(promises).then(responses => {
  // do something with responses
})

I expect the responses of all secondary url requests to be resolved when .then(responses => {}) triggers, yet when this code triggers the responses array is empty.

How can I achieve something like this?

Upvotes: 0

Views: 589

Answers (2)

Flame
Flame

Reputation: 7561

This is logical considering that very first promise.then() statement is asynchronous. The urls.forEach althoughy seemingly asynchronous, it is synchronous. Thus the Promise.all() is called before any promises are pushed to your array.

You could set it up like so:

let promises = [];

urls.forEach(url => {
  promises.push(axios.get(url).then((response) => {
    return axios.get(response.data.url);
  });
});

Promise.all(promises).then(responses => {
  // do something with responses
});

This chains the .then() directly onto the first axios request, which is then pushed onto the promises array.

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 370679

Return the nested axios.get to a mapping callback, so that Promise.all will wait for all nested requests to complete first.

Promise.all(
  urls.map(
    url => axios.get(url).then(
      response => axios.get(response.data.url)
    )
  )
)
  .then((results) => {
    // ...
  })

Upvotes: 2

Related Questions