Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
251 views
in Technique[技术] by (71.8m points)

javascript - Is it possible to use axios.all with a then() for each promise?

I have a React component that triggers an event to fetch data. This results in a dynamic number of stored proc calls to fetch data, and the data from each call is stored in a totally different location. Then I need to re-render once all of the data is received and available. I'm using promises with axios.

Since the number of axios calls is dynamic, I'm building an array and inserting it into axios.all as follows:

let promises = [];

for (let i = 0; i < requests.length; i++) {
    promises.push(axios.get(request[i].url, { params: {...} }));
}

axios.all(promises).then(/* use the data */);

The problem is that each axios request returns data that gets added to an object in a totally different place. Since I have no way to put them all in the correct place in a single then (how would I know which response goes in which location?), I tried doing something like this:

let promises = [];

for (let i = 0; i < requests.length; i++) {
    promises.push(
        axios.get(request[i].url, { params: {...} })
            .then(response => {myObject[request[i].saveLocation] = response.data;})
    );
}

axios.all(promises).then(/* use the data */);

However, this doesn't work as I expected. The then after each get is executed, but not until well after the then attached to axios.all. Obviously this is a problem because my code tries to use the data before it has been saved to the object.

Is there a way to have a separate then call for each axios.get that will be executed after its corresponding promise is resolved, and then have a final then that will be executed only after all of the promises are resolved, to use the data now that the object has been populated?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Okay, so I found a way to do what I needed without using using a then on each get. Since the params passed in to axios.get contain enough info to determine the save location, and since I can read the params back from the response, I can do something like the following:

let promises = [];

for (let i = 0; i < requests.length; i++) {
    promises.push(axios.get(request[i].url, { params: {...} }));
}

axios.all(promises)
    .then(axios.spread((...args) => {
        for (let i = 0; i < args.length; i++) {
            myObject[args[i].config.params.saveLocation] = args[i].data;
        }
    }))
    .then(/* use the data */);

This ensures all the data is received and saved to the object before it is used.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...