1

This all work, except every time i get results in different order. Eg. 2.name, 4.name, 1.name, 3.name, 5.name.

How can I make that every http req finish before starting another one so I can get results in order like in array?

const array = [ '1', '2', '3', '4', '5' ]

array.forEach(el=>{
  axios.get(`/item/${el}`)
     .then(res=>{
         console.log(res.data.name)
   }
})  
  • You can create variabel to save as array. Example const dataName =[...contain res.data.names]. After that, doing looping to combine number and name – Wicak Jan 13 '19 at 13:44
  • You could use await in a loop, provided you're in an async function, something like in the forEach, const res = await axios.get(...); console.log(res); – Countingstuff Jan 13 '19 at 13:45

2 Answers2

1

In order to get the results in the same order, you can simply use Promise.all, or axios.all, but this will executes all the requests in parallel:

const array = [ '1', '2', '3', '4', '5' ];

axios.all(array.map(el => () => axios.get(`/item/${el}`))).then(data => console.log(data));

But, if you need to perform them in order, so sequentially, because maybe in the second request you need to access the response of the first one, you have to chain every next request in the then of the previous one:

const array = [ '1', '2', '3', '4', '5' ];

const requests = array.map(el => () => axios.get(`/item/${el}`));
requests[0]().then(data1 => {
  requests[1]().then(data2 => { ... });
});

Or if you want to avoid the hell of callbacks return the promises and then chai the then blocks:

const array = [ '1', '2', '3', '4', '5' ];

const requests = array.map(el => () => axios.get(`/item/${el}`));
requests[0]()
  .then(data1 => requests[1]())
  .then(data2 => { ... });

Or you can use async/await:

const array = ['1', '2', '3', '4', '5'];
const requests = array.map(el => () => axios.get(`/item/${el}`));

async function performRequests() {
  const res1 = await requests[0]();
  const res2 = await requests[1]();
}

performRequests();
quirimmo
  • 9,800
  • 3
  • 30
  • 45
  • Even the second version doesn’t execute the requests sequentially. – deceze Jan 13 '19 at 13:45
  • oh yeah you are right I forgot to wrap them in extra functions, will update – quirimmo Jan 13 '19 at 13:45
  • There’s gotta be a more elegant way than `requests[1] {...}` to unravel that though... – deceze Jan 13 '19 at 13:49
  • yeah await async if you want to avoid the hell of callbacks – quirimmo Jan 13 '19 at 13:51
  • @deceze if you need to access all the responses sequentially, you cannot create a custom loop on them, because every response will be used in the next request and so on.. – quirimmo Jan 13 '19 at 13:54
  • https://stackoverflow.com/a/43082995/476 – deceze Jan 13 '19 at 14:06
  • yes but this works only if you need to execute them sequentially, but without requiring previous data in next requests. While if in the next ones you need to do some custom thing based on the result of the previous ones, you can't use that generic approach – quirimmo Jan 13 '19 at 14:10
  • @quirimmo thanks, the async/await works like charm... It does not look good but it works... But what if you have 50 items in the array? – SecondClassCitizen Jan 13 '19 at 14:14
  • @SecondClassCitizen the key question is: do you need the data returned by the previous promises in the ones? or you just need to make them in order without needing the returned data? – quirimmo Jan 13 '19 at 14:15
  • @quirimmo I am not sure if I understand the question right. All I need is to extract names of items into one separate array by order like in the array with the items. Your method works but it is to slow, because I have more than 5 items in the initial array. With the way I tried and posted, I get names in a separate array much quicker than now but not in the right order... – SecondClassCitizen Jan 13 '19 at 14:20
  • 1
    in your case, use `Promise.all` or `axios.all`, you just need to preserve the order of the responses, not to execute them sequentially. Does it make sense? Follow the first snippet I posted – quirimmo Jan 13 '19 at 14:21
  • @quirimmo , bravo! With axios all I get all the names quicker and in order that I wanted. Thanks a lot!!! – SecondClassCitizen Jan 13 '19 at 14:32
  • You really shouldn't nest promise handlers like that... one main benefit of promises is not having to next your callbacks in hard-to-read pyramids. It should be more like this: `requests[0]().then(data1 => requests[1]()).then(data2 => { ... });` – IceMetalPunk Jan 14 '19 at 19:50
  • @IceMetalPunk you are absolutely right, updated – quirimmo Jan 15 '19 at 08:23
0

You want something akin to the following

const arr = [1, 2, 3, 4];

function pretendProm(i) {
    return new Promise((resolve, reject) => {
        resolve(arr[i]);
    });
}

arr.forEach(async (res, i) => {
    const x = await pretendProm(i);
    console.log(x);
});

Replace pretendProm(i) with axios.get(...)

Countingstuff
  • 733
  • 5
  • 14