Stefano Toppi
Stefano Toppi

Reputation: 656

Nodejs axios http request loop

I've a problem with Axios and foreach loop. My Api provider support only 5 contemporary call so I want call one by one but when execute this code the each body not wait the the finish call function and receive the error code 429. How can resolve this? thanks.

async function call(url) {
  var options = {
    method: 'GET',
    url: url,
    auth: {
      username: '*****',
      password: '*****'
    }
  };
  var response = await axios.request(options);
  print(response.data["Id"])
}

app.get('/save', async (req, res) => {
  var options = {
    method: 'GET',
    url: 'getListUser',
    auth: {
      username: '***',
      password: '***'
    }
  };
  var response = await axios.request(options);

  response.data["users"].forEach( async (val) => {
    console.log("ENTER");
    var url = 'getDetailUser' + val["id"];
    var res = await call(url); // <- How to wait finish this?
    console.log("EXIT")
  }, (err) => {
      console.log(err)
  })
  res.status(200).send("ok").end();
});

Upvotes: 2

Views: 1572

Answers (3)

deerawan
deerawan

Reputation: 8443

FYI, Promise couldn't work with loop that involves callback ie forEach. Alternatively, you could use for of

try {
  for (const val of response.data['users']) {
    console.log("ENTER");
    var url = 'getDetailUser' + val["id"];
    var res = await call(url); 
    console.log("EXIT")
  }
} catch (error) {
  console.log(error)
}

Upvotes: 2

DevLoverUmar
DevLoverUmar

Reputation: 13933

I would say answer by @Ifaruki is correct with a minor change

await Promise.allSettled(response.data["users"].map(val => {
   var url = 'getDetailUser' + val["id"];
   return call(url); 
}))

For details check the difference. In some cases Promise.all might work but if any of the Promise fails, the whole result of Promise.all will be a rejection.

The code 429 can be resolved by looking at 429 Too Many Requests

Upvotes: 1

Ilijanovic
Ilijanovic

Reputation: 14904

Promise.all() is the way

await Promise.all(response.data["users"].map(val => {
   var url = 'getDetailUser' + val["id"];
   return call(url); 
}))

Upvotes: 0

Related Questions