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?
CodePudding user response:
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) => {
// ...
})
CodePudding user response:
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.