Is it possible to use axios.all with then () for every promise?

I have a React component that fires an event to retrieve data. This results in a dynamic number of stored proc calls to retrieve data, and the data from each call is stored in a completely different place. Then I need to re-render as soon as all the data is received and available. I am using promises using axios.

Since the number of axios calls is dynamic, I build an array and insert 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 every axios request returns data that is added to the object in a completely different place. Since I have no way to place them in the right place in one then (how do I know which answer goes in which place?), I tried to do 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 does not work as I expected. then after each get is executed, but no further, after then attached to axios.all . Obviously, this is a problem because my code is trying to use the data before it is stored in 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 will have a final then , which will be executed only after all promises are resolved to use the data now. when was the object filled?

+5
source share
2 answers

Okay, so I found a way to do what I need without using then for each get . Since the parameters passed to axios.get contain enough information to determine where to save, and since I can read the parameters back from the answer, 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 that all data is received and stored in the object until it is used.

+8
source

If the behavior of your second attempt is indeed so, then this will be a sign that axios not compatible with Promise / A +. The return value then returnback must be the value with which the promise returned by that then is fulfilled. Since this is the promise that you insert into the array, the value that axios.all will return for this promise can only be known after the then callbacks are executed.

The event, although you do not explicitly return the value in the then callback, does not affect the above rule: in this case, the return value is undefined , and this value should be provided by axios.all as soon as the corresponding promise is resolved.

See, in particular, rules 2.2.7, 2.2.7.1, 2.3.2.1, 2.3.2.2 in the specifications of Promise / A + ).

Therefore, I would suggest using Promise / A + compatible promise instead. There are several other libraries, for example request-promise .

Alternatively, you can use your own implementation of ES6 Promise and promise the http.request method yourself.

ES6 offers Promise.all , which guarantees that the allowed values ​​are provided in the same order as promises.

+2
source

Source: https://habr.com/ru/post/1267241/


All Articles